config-value-0.8.3: Simple, layout-based value language similar to YAML or JSON
Copyright(c) Eric Mertens 2020
LicenseISC
Maintaineremertens@gmail.com
Safe HaskellSafe
LanguageHaskell2010

Config.Macro

Description

This module provides assigns meaning to atoms and section names that start with @ and $. It provides processing pass for configuration to use local variables and inclusion to better structure configuration.

Sigils

  • $ starts a variable.
  • @ starts a directive.

Merge key-value mappings using @splice.

Load external configuration with @load.

Variables

Variables are atoms that start with a $ sigil. Variables are defined by setting a variable as a section name. This variable will remain in scope for the remainder of the sections being defined.

Variables used in a value position will be replaced with their previously defined values.

$example: 42
field1: $example
field2: [0, $example]

expands to

field1: 42
field2: [0, 42]

Later variable definitions will shadow earlier definitions.

{ $x: 1, $x: 2, k: $x }

expands to

{ k: 2 }

Scoping examples:

top1:
  a:  $x                     -- BAD: $x not defined yet
  $x: 42                     -- $x is now defined to be 42
  b:  $x                     -- OK: $x was defined above
  c:  {sub1: $x, sub2: [$x]} -- OK: $x in scope in subsections
                             -- note: $x now goes out of scope
top2: $x                     -- BAD: $x no longer in scope

Macros are expanded at their definition site. All variables are resolved before adding the new variable into the environment. Variables are lexically scoped rather than dynamically scoped.

Allowed:

$x: 1
$y: $x -- OK, y is now 1

Not allowed:

$y: $x -- BAD: $x was not in scope
$x: 1
z:  $y

Sections splicing

One sections value can be spliced into another sections value using the @splice directive. It is an error to splice a value that is not a key-value sections.

$xy: { x: 0, y: 1 }
example:
  @splice: $xy
  z: 2

expands to

example:
  x: 0
  y: 1
  z: 2

File loading

The @load directive is intended including configuration from other sources. loadFileWithMacros provides an interpretation of this directive that loads other files. An arbitrary interpretation can be defined with expandMacros'

To load a value define a key-value mapping with a single @load key with a value specifying the location to load from.

x: @load: "fourty-two.cfg"

could expand to

x: 42
Synopsis

Macro expansion primitives

data MacroError a Source #

Errors from macro expansion annotated with the valueAnn from the Value nearest to the problem (typically a file position).

Constructors

UndeclaredVariable a Text

Variable used before its defintion

UnknownDirective a Text

Unknown directive

BadSplice a

Incorrect use of @splice

BadLoad a

Incorrect use of @load

Instances

Instances details
Foldable MacroError Source # 
Instance details

Defined in Config.Macro

Methods

fold :: Monoid m => MacroError m -> m

foldMap :: Monoid m => (a -> m) -> MacroError a -> m

foldMap' :: Monoid m => (a -> m) -> MacroError a -> m

foldr :: (a -> b -> b) -> b -> MacroError a -> b

foldr' :: (a -> b -> b) -> b -> MacroError a -> b

foldl :: (b -> a -> b) -> b -> MacroError a -> b

foldl' :: (b -> a -> b) -> b -> MacroError a -> b

foldr1 :: (a -> a -> a) -> MacroError a -> a

foldl1 :: (a -> a -> a) -> MacroError a -> a

toList :: MacroError a -> [a]

null :: MacroError a -> Bool

length :: MacroError a -> Int

elem :: Eq a => a -> MacroError a -> Bool

maximum :: Ord a => MacroError a -> a

minimum :: Ord a => MacroError a -> a

sum :: Num a => MacroError a -> a

product :: Num a => MacroError a -> a

Traversable MacroError Source # 
Instance details

Defined in Config.Macro

Methods

traverse :: Applicative f => (a -> f b) -> MacroError a -> f (MacroError b)

sequenceA :: Applicative f => MacroError (f a) -> f (MacroError a)

mapM :: Monad m => (a -> m b) -> MacroError a -> m (MacroError b)

sequence :: Monad m => MacroError (m a) -> m (MacroError a)

Functor MacroError Source # 
Instance details

Defined in Config.Macro

Methods

fmap :: (a -> b) -> MacroError a -> MacroError b

(<$) :: a -> MacroError b -> MacroError a

(Typeable a, Show a) => Exception (MacroError a) Source # 
Instance details

Defined in Config.Macro

Methods

toException :: MacroError a -> SomeException

fromException :: SomeException -> Maybe (MacroError a)

displayException :: MacroError a -> String

Read a => Read (MacroError a) Source # 
Instance details

Defined in Config.Macro

Methods

readsPrec :: Int -> ReadS (MacroError a)

readList :: ReadS [MacroError a]

readPrec :: ReadPrec (MacroError a)

readListPrec :: ReadPrec [MacroError a]

Show a => Show (MacroError a) Source # 
Instance details

Defined in Config.Macro

Methods

showsPrec :: Int -> MacroError a -> ShowS

show :: MacroError a -> String

showList :: [MacroError a] -> ShowS

Eq a => Eq (MacroError a) Source # 
Instance details

Defined in Config.Macro

Methods

(==) :: MacroError a -> MacroError a -> Bool

(/=) :: MacroError a -> MacroError a -> Bool

expandMacros :: Value a -> Either (MacroError a) (Value a) Source #

Expand macros in a configuration value.

@load not supported and results in a BadLoad error.

expandMacros' Source #

Arguments

:: Monad m 
=> (forall b. MacroError a -> m b)

failure

-> (Value a -> m (Value a))

@load implementation

-> Map Text (Value a)

variable environment

-> Value a

value to expand

-> m (Value a)

expanded value

Expand macros in a configuration value using a pre-populated environment.

File loader with inclusion

data LoadFileError Source #

Errors thrown by loadFileWithMacros

Constructors

LoadFileParseError FilePath ParseError

failure to parse a file

LoadFileMacroError (MacroError FilePosition)

failure to expand macros

Instances

Instances details
Exception LoadFileError Source # 
Instance details

Defined in Config.Macro

Methods

toException :: LoadFileError -> SomeException

fromException :: SomeException -> Maybe LoadFileError

displayException :: LoadFileError -> String

Read LoadFileError Source # 
Instance details

Defined in Config.Macro

Methods

readsPrec :: Int -> ReadS LoadFileError

readList :: ReadS [LoadFileError]

readPrec :: ReadPrec LoadFileError

readListPrec :: ReadPrec [LoadFileError]

Show LoadFileError Source # 
Instance details

Defined in Config.Macro

Methods

showsPrec :: Int -> LoadFileError -> ShowS

show :: LoadFileError -> String

showList :: [LoadFileError] -> ShowS

Eq LoadFileError Source # 
Instance details

Defined in Config.Macro

data FilePosition Source #

A pair of filepath and position

Constructors

FilePosition FilePath Position 

Instances

Instances details
Read FilePosition Source # 
Instance details

Defined in Config.Macro

Methods

readsPrec :: Int -> ReadS FilePosition

readList :: ReadS [FilePosition]

readPrec :: ReadPrec FilePosition

readListPrec :: ReadPrec [FilePosition]

Show FilePosition Source # 
Instance details

Defined in Config.Macro

Methods

showsPrec :: Int -> FilePosition -> ShowS

show :: FilePosition -> String

showList :: [FilePosition] -> ShowS

Eq FilePosition Source # 
Instance details

Defined in Config.Macro

Methods

(==) :: FilePosition -> FilePosition -> Bool

(/=) :: FilePosition -> FilePosition -> Bool

Ord FilePosition Source # 
Instance details

Defined in Config.Macro

loadFileWithMacros Source #

Arguments

:: (Text -> FilePath -> IO FilePath)

inclusion path resolution

-> FilePath

starting file path

-> IO (Value FilePosition)

macro-expanded config value

Load a configuration value from a given file path.

@load will compute included file path from the given function given the load argument and current configuration file path.

Valid @load arguments are string literals use as arguments to the path resolution function.

Throws IOError from file loads and LoadFileError