Skip to content

Instantly share code, notes, and snippets.

@imsaravana369
Last active July 16, 2024 16:27
Show Gist options
  • Save imsaravana369/97c759ab8a43222a8bb8595d0480f952 to your computer and use it in GitHub Desktop.
Save imsaravana369/97c759ab8a43222a8bb8595d0480f952 to your computer and use it in GitHub Desktop.
module UseConfig where
import Data.Symbol (class IsSymbol, reflectSymbol)
import Effect (Effect)
import Foreign (F, Foreign)
import Prelude
import Split (class SplitOnPeriodWrap) -- [code here](https://gist.github.com/imsaravana369/bbc01f20bef24b6f4f97a365c6bb0410)
import Type.Proxy (Proxy(..))
import Control.Monad.Except (runExcept)
import Data.Either (Either(..))
foreign import getConfigJson :: String -> Effect Foreign
newtype ScreenConfig = ScreenConfig { name :: String}
newtype MessageConfig = MessageConfig { msg :: String}
derive newtype instance Show ScreenConfig
derive newtype instance Show MessageConfig
class DecodeConfig :: Symbol -> Type -> Constraint
class (IsSymbol path) <= DecodeConfig path a | path -> a where
decodeConfig :: Proxy path -> Foreign -> F a
instance DecodeConfig "MessageConfig" MessageConfig where
decodeConfig _ fgn = pure $ MessageConfig { msg : "hello"} -- just a mock
instance DecodeConfig "ScreenConfig" ScreenConfig where
decodeConfig _ fgn = pure $ ScreenConfig { name : "screen1"} -- just a mock
class UseConfig :: Symbol -> Type -> Constraint
class (IsSymbol path) <= UseConfig path a | path -> a where
getConfig :: Proxy path -> Effect (Either String a)
instance ( IsSymbol fullpath
-- SplitOnPeriodWrap takes two arguments,
-- * The first argument corresponds to the whole path a symbol
-- * The second argument corresponds to the last segment in a dot seperated symbol
-- [code here](https://gist.github.com/imsaravana369/bbc01f20bef24b6f4f97a365c6bb0410)
, SplitOnPeriodWrap fullpath path'
, DecodeConfig path' ret
) => UseConfig fullpath ret where
getConfig _ = do
fgn <- getConfigJson (reflectSymbol (Proxy @fullpath))
pure case runExcept $ decodeConfig (Proxy @path') fgn of
Right a -> Right a
Left a -> Left (show a)
getConfig' :: forall path suffixpath val
. IsSymbol path
=> DecodeConfig suffixpath val
=> SplitOnPeriodWrap path suffixpath
=> Proxy path
-> Effect (Either String val)
getConfig' = getConfig
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment