{-# LANGUAGE DeriveDataTypeable, FlexibleInstances #-}

-- |
-- Module:      Data.Configurator.Types.Internal
-- Copyright:   (c) 2011 MailRank, Inc.
-- License:     BSD3
-- Maintainer:  Bryan O'Sullivan <bos@serpentine.com>
-- Stability:   experimental
-- Portability: portable
--
-- Types for working with configuration files.

module Data.Configurator.Types.Internal
    (
      BaseConfig(..)
    , Config(..)
    , Configured(..)
    , AutoConfig(..)
    , Worth(..)
    , Name
    , Value(..)
    , Binding
    , Path
    , Directive(..)
    , ConfigError(..)
    , KeyError(..)
    , Interpolate(..)
    , Pattern(..)
    , exact
    , prefix
    , ChangeHandler
    ) where

import Control.Exception
import Data.Data (Data)
import Data.Hashable (Hashable(..))
import Data.IORef (IORef)
import Data.List (isSuffixOf)
import Data.String (IsString(..))
import Data.Text (Text)
import qualified Data.Text as T
import Data.Typeable (Typeable)
import Prelude hiding (lookup)
import qualified Data.HashMap.Lazy as H

data Worth a = Required { forall a. Worth a -> a
worth :: a }
             | Optional { worth :: a }
               deriving (Int -> Worth a -> ShowS
[Worth a] -> ShowS
Worth a -> String
(Int -> Worth a -> ShowS)
-> (Worth a -> String) -> ([Worth a] -> ShowS) -> Show (Worth a)
forall a. Show a => Int -> Worth a -> ShowS
forall a. Show a => [Worth a] -> ShowS
forall a. Show a => Worth a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Worth a -> ShowS
showsPrec :: Int -> Worth a -> ShowS
$cshow :: forall a. Show a => Worth a -> String
show :: Worth a -> String
$cshowList :: forall a. Show a => [Worth a] -> ShowS
showList :: [Worth a] -> ShowS
Show, Typeable)

instance IsString (Worth FilePath) where
    fromString :: String -> Worth String
fromString = String -> Worth String
forall a. a -> Worth a
Required

instance (Eq a) => Eq (Worth a) where
    Worth a
a == :: Worth a -> Worth a -> Bool
== Worth a
b = Worth a -> a
forall a. Worth a -> a
worth Worth a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== Worth a -> a
forall a. Worth a -> a
worth Worth a
b

instance (Hashable a) => Hashable (Worth a) where
    hashWithSalt :: Int -> Worth a -> Int
hashWithSalt Int
salt Worth a
v = Int -> a -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt (Worth a -> a
forall a. Worth a -> a
worth Worth a
v)

-- | Global configuration data.  This is the top-level config from which
-- 'Config' values are derived by choosing a root location.
data BaseConfig = BaseConfig {
      BaseConfig -> Maybe AutoConfig
cfgAuto :: Maybe AutoConfig
    , BaseConfig -> IORef [(Name, Worth Name)]
cfgPaths :: IORef [(Name, Worth Path)]
    -- ^ The files from which the 'Config' was loaded.
    , BaseConfig -> IORef (HashMap Name Value)
cfgMap :: IORef (H.HashMap Name Value)
    , BaseConfig -> IORef (HashMap Pattern [ChangeHandler])
cfgSubs :: IORef (H.HashMap Pattern [ChangeHandler])
    }

-- | Configuration data.
data Config = Config { Config -> Name
root :: Text, Config -> BaseConfig
baseCfg :: BaseConfig }

instance Functor Worth where
    fmap :: forall a b. (a -> b) -> Worth a -> Worth b
fmap a -> b
f (Required a
a) = b -> Worth b
forall a. a -> Worth a
Required (a -> b
f a
a)
    fmap a -> b
f (Optional a
a) = b -> Worth b
forall a. a -> Worth a
Optional (a -> b
f a
a)

-- | An action to be invoked if a configuration property is changed.
--
-- If this action is invoked and throws an exception, the 'onError'
-- function will be called.
type ChangeHandler = Name
                   -- ^ Name of the changed property.
                   -> Maybe Value
                   -- ^ Its new value, or 'Nothing' if it has
                   -- vanished.
                   -> IO ()

-- | A pattern specifying the name of a property that has changed.
--
-- This type is an instance of the 'IsString' class.  If you use the
-- @OverloadedStrings@ language extension and want to write a
-- 'prefix'-matching pattern as a literal string, do so by suffixing
-- it with \"@.*@\", for example as follows:
--
-- > "foo.*"
--
-- If a pattern written as a literal string does not end with
-- \"@.*@\", it is assumed to be 'exact'.
data Pattern = Exact Name
             -- ^ An exact match.
             | Prefix Name
             -- ^ A prefix match.  Given @'Prefix' \"foo\"@, this will
             -- match @\"foo.bar\"@, but not @\"foo\"@ or
             -- @\"foobar\"@.
               deriving (Pattern -> Pattern -> Bool
(Pattern -> Pattern -> Bool)
-> (Pattern -> Pattern -> Bool) -> Eq Pattern
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Pattern -> Pattern -> Bool
== :: Pattern -> Pattern -> Bool
$c/= :: Pattern -> Pattern -> Bool
/= :: Pattern -> Pattern -> Bool
Eq, Int -> Pattern -> ShowS
[Pattern] -> ShowS
Pattern -> String
(Int -> Pattern -> ShowS)
-> (Pattern -> String) -> ([Pattern] -> ShowS) -> Show Pattern
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Pattern -> ShowS
showsPrec :: Int -> Pattern -> ShowS
$cshow :: Pattern -> String
show :: Pattern -> String
$cshowList :: [Pattern] -> ShowS
showList :: [Pattern] -> ShowS
Show, Typeable, Typeable Pattern
Typeable Pattern
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Pattern -> c Pattern)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Pattern)
-> (Pattern -> Constr)
-> (Pattern -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Pattern))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern))
-> ((forall b. Data b => b -> b) -> Pattern -> Pattern)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r)
-> (forall u. (forall d. Data d => d -> u) -> Pattern -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern)
-> Data Pattern
Pattern -> Constr
Pattern -> DataType
(forall b. Data b => b -> b) -> Pattern -> Pattern
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u
forall u. (forall d. Data d => d -> u) -> Pattern -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Pattern -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Pattern -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Pattern
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pattern -> c Pattern
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Pattern)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pattern -> c Pattern
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Pattern -> c Pattern
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Pattern
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Pattern
$ctoConstr :: Pattern -> Constr
toConstr :: Pattern -> Constr
$cdataTypeOf :: Pattern -> DataType
dataTypeOf :: Pattern -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Pattern)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Pattern)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern)
$cgmapT :: (forall b. Data b => b -> b) -> Pattern -> Pattern
gmapT :: (forall b. Data b => b -> b) -> Pattern -> Pattern
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Pattern -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Pattern -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Pattern -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Pattern -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Pattern -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Pattern -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Pattern -> m Pattern
Data)

-- | A pattern that must match exactly.
exact :: Text -> Pattern
exact :: Name -> Pattern
exact = Name -> Pattern
Exact

-- | A pattern that matches on a prefix of a property name.  Given
-- @\"foo\"@, this will match @\"foo.bar\"@, but not @\"foo\"@ or
-- @\"foobar\"@.
prefix :: Text -> Pattern
prefix :: Name -> Pattern
prefix Name
p = Name -> Pattern
Prefix (Name
p Name -> Char -> Name
`T.snoc` Char
'.')

instance IsString Pattern where
    fromString :: String -> Pattern
fromString String
s
        | String
".*" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
s = Name -> Pattern
Prefix (Name -> Pattern) -> (String -> Name) -> String -> Pattern
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Name -> Name
Name -> Name
T.init (Name -> Name) -> (String -> Name) -> String -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Name
T.pack (String -> Pattern) -> String -> Pattern
forall a b. (a -> b) -> a -> b
$ String
s
        | Bool
otherwise           = Name -> Pattern
Exact (String -> Name
T.pack String
s)

instance Hashable Pattern where
    hashWithSalt :: Int -> Pattern -> Int
hashWithSalt Int
salt (Exact Name
n)  = Int -> Name -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt Name
n
    hashWithSalt Int
salt (Prefix Name
n) = Int -> Name -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt Name
n

-- | This class represents types that can be automatically and safely
-- converted /from/ a 'Value' /to/ a destination type.  If conversion
-- fails because the types are not compatible, 'Nothing' is returned.
--
-- For an example of compatibility, a 'Value' of 'Bool' 'True' cannot
-- be 'convert'ed to an 'Int'.
class Configured a where
    convert :: Value -> Maybe a

    convertList :: Value -> Maybe [a]
    convertList (List [Value]
xs) = (Value -> Maybe a) -> [Value] -> Maybe [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Value -> Maybe a
forall a. Configured a => Value -> Maybe a
convert [Value]
xs
    convertList Value
_         = Maybe [a]
forall a. Maybe a
Nothing

instance Configured a => Configured [a] where
    convert :: Value -> Maybe [a]
convert = Value -> Maybe [a]
forall a. Configured a => Value -> Maybe [a]
convertList

-- | An error occurred while processing a configuration file.
data ConfigError = ParseError FilePath String
                   deriving (Int -> ConfigError -> ShowS
[ConfigError] -> ShowS
ConfigError -> String
(Int -> ConfigError -> ShowS)
-> (ConfigError -> String)
-> ([ConfigError] -> ShowS)
-> Show ConfigError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ConfigError -> ShowS
showsPrec :: Int -> ConfigError -> ShowS
$cshow :: ConfigError -> String
show :: ConfigError -> String
$cshowList :: [ConfigError] -> ShowS
showList :: [ConfigError] -> ShowS
Show, Typeable)

instance Exception ConfigError

-- | An error occurred while lookup up the given 'Name'.
data KeyError = KeyError Name
              deriving (Int -> KeyError -> ShowS
[KeyError] -> ShowS
KeyError -> String
(Int -> KeyError -> ShowS)
-> (KeyError -> String) -> ([KeyError] -> ShowS) -> Show KeyError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyError -> ShowS
showsPrec :: Int -> KeyError -> ShowS
$cshow :: KeyError -> String
show :: KeyError -> String
$cshowList :: [KeyError] -> ShowS
showList :: [KeyError] -> ShowS
Show, Typeable)

instance Exception KeyError

-- | Directions for automatically reloading 'Config' data.
data AutoConfig = AutoConfig {
      AutoConfig -> Int
interval :: Int
    -- ^ Interval (in seconds) at which to check for updates to config
    -- files.  The smallest allowed interval is one second.
    , AutoConfig -> SomeException -> IO ()
onError :: SomeException -> IO ()
    -- ^ Action invoked when an attempt to reload a 'Config' or notify
    -- a 'ChangeHandler' causes an exception to be thrown.
    --
    -- If this action rethrows its exception or throws a new
    -- exception, the modification checking thread will be killed.
    -- You may want your application to treat that as a fatal error,
    -- as its configuration may no longer be consistent.
    } deriving (Typeable)

instance Show AutoConfig where
    show :: AutoConfig -> String
show AutoConfig
c = String
"AutoConfig {interval = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (AutoConfig -> Int
interval AutoConfig
c) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"}"

-- | The name of a 'Config' value.
type Name = Text

-- | A packed 'FilePath'.
type Path = Text

-- | A name-value binding.
type Binding = (Name,Value)

-- | A directive in a configuration file.
data Directive = Import Path
               | Bind Name Value
               | Group Name [Directive]
                 deriving (Directive -> Directive -> Bool
(Directive -> Directive -> Bool)
-> (Directive -> Directive -> Bool) -> Eq Directive
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Directive -> Directive -> Bool
== :: Directive -> Directive -> Bool
$c/= :: Directive -> Directive -> Bool
/= :: Directive -> Directive -> Bool
Eq, Int -> Directive -> ShowS
[Directive] -> ShowS
Directive -> String
(Int -> Directive -> ShowS)
-> (Directive -> String)
-> ([Directive] -> ShowS)
-> Show Directive
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Directive -> ShowS
showsPrec :: Int -> Directive -> ShowS
$cshow :: Directive -> String
show :: Directive -> String
$cshowList :: [Directive] -> ShowS
showList :: [Directive] -> ShowS
Show, Typeable, Typeable Directive
Typeable Directive
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Directive -> c Directive)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Directive)
-> (Directive -> Constr)
-> (Directive -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Directive))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive))
-> ((forall b. Data b => b -> b) -> Directive -> Directive)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r)
-> (forall u. (forall d. Data d => d -> u) -> Directive -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Directive -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive)
-> Data Directive
Directive -> Constr
Directive -> DataType
(forall b. Data b => b -> b) -> Directive -> Directive
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Directive -> u
forall u. (forall d. Data d => d -> u) -> Directive -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Directive -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Directive -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Directive
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Directive -> c Directive
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Directive)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Directive -> c Directive
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Directive -> c Directive
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Directive
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Directive
$ctoConstr :: Directive -> Constr
toConstr :: Directive -> Constr
$cdataTypeOf :: Directive -> DataType
dataTypeOf :: Directive -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Directive)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Directive)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive)
$cgmapT :: (forall b. Data b => b -> b) -> Directive -> Directive
gmapT :: (forall b. Data b => b -> b) -> Directive -> Directive
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Directive -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Directive -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Directive -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Directive -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Directive -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Directive -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Directive -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Directive -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Directive -> m Directive
Data)

-- | A value in a 'Config'.
data Value = Bool Bool
           -- ^ A Boolean. Represented in a configuration file as @on@
           -- or @off@, @true@ or @false@ (case sensitive).
           | String Text
           -- ^ A Unicode string.  Represented in a configuration file
           -- as text surrounded by double quotes.
           --
           -- Escape sequences:
           --
           -- * @\\n@ - newline
           --
           -- * @\\r@ - carriage return
           --
           -- * @\\t@ - horizontal tab
           --
           -- * @\\\\@ - backslash
           --
           -- * @\\\"@ - quotes
           --
           -- * @\\u@/xxxx/ - Unicode character, encoded as four
           --   hexadecimal digits
           --
           -- * @\\u@/xxxx/@\\u@/xxxx/ - Unicode character (as two
           --   UTF-16 surrogates)
           | Number Rational
           -- ^ Integer.
           | List [Value]
           -- ^ Heterogeneous list.  Represented in a configuration
           -- file as an opening square bracket \"@[@\", followed by a
           -- comma-separated series of values, ending with a closing
           -- square bracket \"@]@\".
             deriving (Value -> Value -> Bool
(Value -> Value -> Bool) -> (Value -> Value -> Bool) -> Eq Value
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Value -> Value -> Bool
== :: Value -> Value -> Bool
$c/= :: Value -> Value -> Bool
/= :: Value -> Value -> Bool
Eq, Int -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Int -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Value -> ShowS
showsPrec :: Int -> Value -> ShowS
$cshow :: Value -> String
show :: Value -> String
$cshowList :: [Value] -> ShowS
showList :: [Value] -> ShowS
Show, Typeable, Typeable Value
Typeable Value
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Value -> c Value)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Value)
-> (Value -> Constr)
-> (Value -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Value))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value))
-> ((forall b. Data b => b -> b) -> Value -> Value)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r)
-> (forall u. (forall d. Data d => d -> u) -> Value -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Value -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Value -> m Value)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Value -> m Value)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Value -> m Value)
-> Data Value
Value -> Constr
Value -> DataType
(forall b. Data b => b -> b) -> Value -> Value
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Value -> u
forall u. (forall d. Data d => d -> u) -> Value -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Value -> m Value
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Value -> m Value
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Value
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Value -> c Value
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Value)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Value -> c Value
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Value -> c Value
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Value
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Value
$ctoConstr :: Value -> Constr
toConstr :: Value -> Constr
$cdataTypeOf :: Value -> DataType
dataTypeOf :: Value -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Value)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Value)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value)
$cgmapT :: (forall b. Data b => b -> b) -> Value -> Value
gmapT :: (forall b. Data b => b -> b) -> Value -> Value
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Value -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Value -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Value -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Value -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Value -> m Value
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Value -> m Value
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Value -> m Value
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Value -> m Value
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Value -> m Value
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Value -> m Value
Data)

-- | An interpolation directive.
data Interpolate = Literal Text
                 | Interpolate Text
                   deriving (Interpolate -> Interpolate -> Bool
(Interpolate -> Interpolate -> Bool)
-> (Interpolate -> Interpolate -> Bool) -> Eq Interpolate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Interpolate -> Interpolate -> Bool
== :: Interpolate -> Interpolate -> Bool
$c/= :: Interpolate -> Interpolate -> Bool
/= :: Interpolate -> Interpolate -> Bool
Eq, Int -> Interpolate -> ShowS
[Interpolate] -> ShowS
Interpolate -> String
(Int -> Interpolate -> ShowS)
-> (Interpolate -> String)
-> ([Interpolate] -> ShowS)
-> Show Interpolate
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Interpolate -> ShowS
showsPrec :: Int -> Interpolate -> ShowS
$cshow :: Interpolate -> String
show :: Interpolate -> String
$cshowList :: [Interpolate] -> ShowS
showList :: [Interpolate] -> ShowS
Show)