config-parser-1.2.0.0: Text/ConfigParser/Types.hs
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}
{-# OPTIONS_HADDOCK hide #-}
module Text.ConfigParser.Types where
import Text.Parsec (spaces, char, many1)
import Text.Parsec.Char (noneOf)
import Text.Parsec.Text (Parser)
type Key = String
-- ^ Key-value pair to parse from a config file.
data ConfigOption c
= forall a. ConfigOption
{ key :: Key -- ^ Key name.
, required :: Bool -- ^ Whether it is an error to omit this key.
, parser :: Parser a -- ^ Parser for the given value type.
, action :: a -> c -> c -- ^ How the value should change the state @c@.
}
optionalCO, requiredCO :: Key -> Parser a -> (a -> c -> c) -> ConfigOption c
optionalCO k = ConfigOption k False
requiredCO k = ConfigOption k True
-- | Parameters for a parser that takes a config file and produces a @c@. Use
-- the 'ConfigParser' constructor if you want to specify your own 'lineParser'
-- or 'commentStart'. Otherwise, use the 'configParser' smart constructor.
data ConfigParser c = ConfigParser
{ keyValue :: forall a. Parser Key -> Parser a -> Parser a
-- ^ Specifies how a key and a value parser should be represented in the
-- config file, e.g., @key = value@, or @key: value@. The first parameter
-- will be either be @Text.Parsec.string (key (co::ConfigOption c))@ or
-- @keyIdentifier@. The second parameter will be
-- @parser (co::ConfigOption c)@.
, lineCommentInit :: [String]
-- ^ Strings to start a line comment, such as @#@, @--@, or @//@. All
-- characters following this string up to the following newline or EOF
-- will be removed. You can use the string without starting a comment by
-- escaping it with a backslash, e.g. @\\#@ or @\\--@.
, keyIdentifier :: Parser Key
-- ^ This is the general form of an identifier to be passed as the first
-- parameter of @keyValue@. Having a general form allows us to correctly
-- detect invalid (e.g., typoed) keys. For example, the @keyIdentifier@
-- corresponding to @defaultKeyValue@ is @many1 (noneOf "\\r\\v\\n\\t =")@.
, defaults :: c
-- ^ Initial @c@ to fold each 'ConfigOption' action over.
, options :: [ConfigOption c]
-- ^ List of key-value pairs to parse from the config file. Any key in the
-- config file that doesn't appear here will result in parse error.
}
-- | Smart constructor for a 'ConfigParser' that uses a default syntax like
-- @key = value@ and line comments starting with @#@.
configParser :: c -> [ConfigOption c] -> ConfigParser c
configParser =
ConfigParser defaultKeyValue defaultLineCommentInit defaultKeyIdentifier
-- | The @keyIdentifier@ corresponding to @defaultKeyValue@.
defaultKeyIdentifier :: Parser Key
defaultKeyIdentifier = many1 $ noneOf "\n\t\r\v ="
-- | Default syntax like @key = value@.
defaultKeyValue :: Parser Key -> Parser a -> Parser a
defaultKeyValue k p = k *> separator *> p
where
separator = spaces *> char '=' <* spaces
-- | Default line comment like @# comment text@.
defaultLineCommentInit :: [String]
defaultLineCommentInit = ["#"]