conferer-0.2.0.0: src/Conferer/Core.hs
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 (throw)
import Conferer.Provider.Simple
import Conferer.Types
-- | Most Basic function to interact directly with a 'Config'. It always returns
-- 'Text' in the case of success and implements the logic to traverse
-- providers inside the 'Config'.
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
-- | Fetch a value from a config key that's parsed using the FetchFromConfig
-- instance.
--
-- This function throws an exception if the key is not found.
getFromConfig :: forall a. (Typeable a, FetchFromConfig a) => Key -> Config -> IO a
getFromConfig key config =
fromMaybe (throw $ FailedToFetchError key (typeRep (Proxy :: Proxy a)))
<$> fetch key config
-- | Create a new 'Key' by concatenating two existing keys.
(/.) :: Key -> Key -> Key
parent /. child = Path (unKey parent ++ unKey child)
-- | The empty configuration, this 'Config' is used as the base for
-- most config creating functions.
emptyConfig :: Config
emptyConfig = Config [] Map.empty
withDefaults :: [(Key, Text)] -> Config -> Config
withDefaults configMap config =
config { defaults = Map.fromList configMap }
-- | Instantiate a 'ProviderCreator' using the 'emptyConfig'
mkStandaloneProvider :: ProviderCreator -> IO Provider
mkStandaloneProvider mkProvider =
mkProvider emptyConfig
-- | Instantiate a 'Provider' using an 'ProviderCretor' and a 'Config' and add
-- to the config
addProvider :: ProviderCreator -> Config -> IO Config
addProvider mkProvider config = do
newProvider <- mkProvider config
return $
config
{ providers = providers config ++ [ newProvider ]
}
-- | Same as 'getKey' but it throws if the 'Key' isn't found
unsafeGetKey :: Key -> Config -> IO Text
unsafeGetKey key config =
fromMaybe (throw $ FailedToFetchError key (typeRep (Proxy :: Proxy Text)))
<$> getKey key config