conferer-0.3.0.0: Configuration management library

Copyright(c) 2019 Lucas David Traverso
LicenseMIT
MaintainerLucas David Traverso <lucas6246@gmail.com>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

Conferer

Contents

Description

Types and functions for managing configuration effectively

Synopsis

How to use this library

This is the most basic example: which uses the default configuration to get a configuration for warp, which can be overriden via env vars, command line arguments of .properties files

import Conferer
import Conferer.FromConfig.Warp () -- from package conferer-warp

main = do
  config <- defaultConfig "awesomeapp"
  warpSettings <- getFromConfig "warp" config
  runSettings warpSettings application

In the above example we see that we are getting a configuration value for warp under the key warp, so for example to override it's default value provided by warp the config keys for warp will always look like warp.something, for example to override the port for warp (3000 by default) we could call our program as ./my_program --warp.port=8000.

There are two sides to conferer: Getting configuration for other libraries like warp, hspec, snap, etc. and the way we choose to provide values like json files, properties files, env vars, etc.

Getting configuration for existing libraries

There is a typeclass FromConfig that defines how to get a type from a config, they are implemented in different packages since the weight of the dependencies would be too high, the package is usually named as conferer-DEPENDENCY where DEPENDENCY is the name of the dependency ( for example: conferer-snap, conferer-warp, conferer-hspec), if you find a library without a conferer port for its config you can create an issue or maybe even create the library yourself!

Providing key value pairs for configuration

There is one important type in conferer: Config from which, given a key (eg: warp) you can get anything that implements FromConfig (like Settings)

Internally a Config is made of many Providers which have a simpler interface:

getKeyInProvider :: Provider -> Key -> IO (Maybe Text)

Most configuration providers can be abstracted away as Map String String, and they can use whatever logic they want to turn conferer keys (a list of strings) into a place to look for a string, (for example the env provider requires a string to namespace the env vars that can affect the configuration)

Once you have your Provider you can add it to a Config using the addProvider function. One final note: each provider has a different priority, which depends on when is was added to the config (Providers added later have lower priority) so the config searches keys in providers in the same order they were added.

class FromConfig a where Source #

Main typeclass for defining the way to get values from config, hiding the Text based nature of the Providers. updated using a config, so for example a Warp.Settings can get updated from a config, but that doesn't make much sense for something like an Int

You'd normally would never implement this typeclass, if you want to implement FromConfig you should implement that directly, and if you want to use DefaultConfig and FromConfig to implement FromConfig you should let the default Generics based implementation do it's thing

Minimal complete definition

Nothing

Instances
FromConfig Bool Source # 
Instance details

Defined in Conferer.FromConfig.Basics

FromConfig Float Source # 
Instance details

Defined in Conferer.FromConfig.Basics

FromConfig Int Source # 
Instance details

Defined in Conferer.FromConfig.Basics

FromConfig Integer Source # 
Instance details

Defined in Conferer.FromConfig.Basics

FromConfig String Source # 
Instance details

Defined in Conferer.FromConfig.Basics

FromConfig ByteString Source # 
Instance details

Defined in Conferer.FromConfig.Basics

FromConfig Text Source # 
Instance details

Defined in Conferer.FromConfig.Basics

FromConfig a => FromConfig (Maybe a) Source # 
Instance details

Defined in Conferer.FromConfig.Basics

class DefaultConfig a where Source #

Default defining instance

Here a Nothing means that the value didn't appear in the config, some instances never return a value since they have defaults that can never fail

Methods

configDef :: a Source #

Instances
DefaultConfig (Maybe a) Source # 
Instance details

Defined in Conferer.FromConfig.Basics

Methods

configDef :: Maybe a Source #

type ProviderCreator = Config -> IO Provider Source #

The type for creating a provider given a Config, some providers require a certain configuration to be initialized (for example: the redis provider needs connection info to connect to the server)

data Config Source #

Core type that the user of this library interact with, in the future it may contain more this besides a list of providers

newtype Key Source #

The way to index Providers, basically list of names that will be adapted to whatever the provider needs

Constructors

Path 

Fields

Instances
Eq Key Source # 
Instance details

Defined in Conferer.Types

Methods

(==) :: Key -> Key -> Bool #

(/=) :: Key -> Key -> Bool #

Ord Key Source # 
Instance details

Defined in Conferer.Types

Methods

compare :: Key -> Key -> Ordering #

(<) :: Key -> Key -> Bool #

(<=) :: Key -> Key -> Bool #

(>) :: Key -> Key -> Bool #

(>=) :: Key -> Key -> Bool #

max :: Key -> Key -> Key #

min :: Key -> Key -> Key #

Show Key Source # 
Instance details

Defined in Conferer.Types

Methods

showsPrec :: Int -> Key -> ShowS #

show :: Key -> String #

showList :: [Key] -> ShowS #

IsString Key Source # 
Instance details

Defined in Conferer.Types

Methods

fromString :: String -> Key #

data Provider Source #

Core interface for library provided configuration, basically consists of getting a Key and informing returning a maybe signaling the value and if it's present in that specific provider

Constructors

Provider 

Fields

getKey :: Key -> Config -> IO (Maybe Text) Source #

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.

getFromConfig :: forall a. (Typeable a, FromConfig a, DefaultConfig a) => Key -> Config -> IO a Source #

Fetch a value from a config under some specific key that's parsed using the FromConfig instance, and as a default it uses the value from DefaultConfig.

Notes: - This function may throw an exception if parsing fails for any subkey

getFromRootConfig :: forall a. (Typeable a, FromConfig a, DefaultConfig a) => Config -> IO a Source #

Same as getFromConfig using the root key

Notes: - This function may throw an exception if parsing fails for any subkey

getFromConfigWithDefault :: forall a. (Typeable a, FromConfig a) => Key -> Config -> a -> IO a Source #

Same as getFromConfig but with a user defined default (instead of DefaultConfig instance)

Useful for fetching primitive types

safeGetFromConfig :: forall a. (Typeable a, FromConfig a, DefaultConfig a) => Key -> Config -> IO (Maybe a) Source #

Fetch a value from a config key that's parsed using the FromConfig instance.

Note: This function does not use default so the value must be fully defined by the config only, meaning using this function for many records will always result in Nothing (if the record contains a value that can never be retrieved like a function)

safeGetFromConfigWithDefault :: forall a. (Typeable a, FromConfig a) => Key -> Config -> a -> IO (Maybe a) Source #

Same as safeGetFromConfig but with a user defined default

(/.) :: Key -> Key -> Key Source #

Create a new Key by concatenating two existing keys.

emptyConfig :: Config Source #

The empty configuration, this Config is used as the base for most config creating functions.

addProvider :: ProviderCreator -> Config -> IO Config Source #

Instantiate a Provider using an ProviderCretor and a Config and add to the config

unsafeGetKey :: Key -> Config -> IO Text Source #

Same as getKey but it throws if the Key isn't found

defaultConfig :: Text -> IO Config Source #

Default config which reads from command line arguments, env vars and property files

defaultConfigWithDefaults :: Text -> [(Key, Text)] -> IO Config Source #

Default config which reads from command line arguments, env vars, property files and some default key/values

newtype Key Source #

The way to index Providers, basically list of names that will be adapted to whatever the provider needs

Constructors

Path 

Fields

Instances
Eq Key Source # 
Instance details

Defined in Conferer.Types

Methods

(==) :: Key -> Key -> Bool #

(/=) :: Key -> Key -> Bool #

Ord Key Source # 
Instance details

Defined in Conferer.Types

Methods

compare :: Key -> Key -> Ordering #

(<) :: Key -> Key -> Bool #

(<=) :: Key -> Key -> Bool #

(>) :: Key -> Key -> Bool #

(>=) :: Key -> Key -> Bool #

max :: Key -> Key -> Key #

min :: Key -> Key -> Key #

Show Key Source # 
Instance details

Defined in Conferer.Types

Methods

showsPrec :: Int -> Key -> ShowS #

show :: Key -> String #

showList :: [Key] -> ShowS #

IsString Key Source # 
Instance details

Defined in Conferer.Types

Methods

fromString :: String -> Key #

Providers

Re-Exports

(&) :: a -> (a -> b) -> b infixl 1 #

& is a reverse application operator. This provides notational convenience. Its precedence is one higher than that of the forward application operator $, which allows & to be nested in $.

>>> 5 & (+1) & show
"6"

Since: base-4.8.0.0