{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE FlexibleContexts #-}
module Conferer.Core where
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import Data.Typeable (Typeable, Proxy(..), typeRep)
import Control.Exception (try, throw, throwIO, evaluate)
import Conferer.Provider.Simple
import Conferer.Types
getKey :: Key -> Config -> IO (Maybe Text)
getKey k config =
go $ providers config ++ [mkPureMapProvider (defaults config)]
where
go [] = return Nothing
go (provider:providers) = do
res <- getKeyInProvider provider k
case res of
Just t -> return $ Just t
Nothing -> go providers
getFromConfig :: forall a. (Typeable a, FromConfig a, DefaultConfig a) => Key -> Config -> IO a
getFromConfig key config =
getFromConfigWithDefault key config configDef
getFromRootConfig :: forall a. (Typeable a, FromConfig a, DefaultConfig a) => Config -> IO a
getFromRootConfig config =
getFromConfig "" config
getFromConfigWithDefault :: forall a. (Typeable a, FromConfig a) => Key -> Config -> a -> IO a
getFromConfigWithDefault key config configDefault =
safeGetFromConfigWithDefault key config configDefault
>>= \case
Just value -> do
evaluate value
Nothing ->
throwIO $ FailedToFetchError key (typeRep (Proxy :: Proxy a))
safeGetFromConfig :: forall a. (Typeable a, FromConfig a, DefaultConfig a) => Key -> Config -> IO (Maybe a)
safeGetFromConfig key config =
safeGetFromConfigWithDefault key config configDef
safeGetFromConfigWithDefault :: forall a. (Typeable a, FromConfig a) => Key -> Config -> a -> IO (Maybe a)
safeGetFromConfigWithDefault key config configDefault = do
totalValue <- evaluate =<< fetchFromConfig key config
case totalValue of
Just value -> do
Just <$> evaluate value
Nothing -> do
result :: Either FailedToFetchError a <- try . (evaluate =<<) . updateFromConfig key config $ configDefault
case result of
Right a -> Just <$> evaluate a
Left e -> return Nothing
(/.) :: Key -> Key -> Key
parent /. child = Path (unKey parent ++ unKey child)
emptyConfig :: Config
emptyConfig = Config [] Map.empty
withDefaults :: [(Key, Text)] -> Config -> Config
withDefaults configMap config =
config { defaults = Map.fromList configMap }
mkStandaloneProvider :: ProviderCreator -> IO Provider
mkStandaloneProvider mkProvider =
mkProvider emptyConfig
addProvider :: ProviderCreator -> Config -> IO Config
addProvider mkProvider config = do
newProvider <- mkProvider config
return $
config
{ providers = providers config ++ [ newProvider ]
}
unsafeGetKey :: Key -> Config -> IO Text
unsafeGetKey key config =
fromMaybe (throw $ FailedToFetchError key (typeRep (Proxy :: Proxy Text)))
<$> getKey key config