    {-
    Copyright (C) 2004-2008 John Goerzen <jgoerzen@complete.org>

    This program is free software; you can redistribute it and/or modify it, as
    specified in the COPYRIGHT file, under the terms of either version 2.1 of
    the LGPL (or, at your option, any later version) or the 3-clause BSD license.
    -}

    {- |
       Module     : Data.ConfigFile.Types
       Copyright  : Copyright (C) 2004-2008 John Goerzen
       License    : Either LGPL or BSD3, as specified in the COPYRIGHT file.

       Maintainer : John Goerzen <jgoerzen@complete.org>
       Stability  : provisional
       Portability: portable

    Internal types for "Data.ConfigFile".  This module is not intended to be
    used directly by your programs.

    Copyright (c) 2004-2008 John Goerzen, jgoerzen\@complete.org

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    -}

    module Data.ConfigFile.Types (
                                        CPOptions, CPData,
                                        CPErrorData(..), CPError, {-CPResult,-}
                                        ConfigParser(..),
                                        SectionSpec,
                                        OptionSpec,
                                        ParseOutput
                                       ) where
    import qualified Data.Map as Map
    import Data.Char
    import Control.Monad.Error

    {- | Internal output from parser -}
    type ParseOutput = [(String, [(String, String)])]

    {- | Names of sections -}
    type SectionSpec = String

    {- | Names of options -}
    type OptionSpec = String

    {- | Storage of options. -}
    type CPOptions = Map.Map OptionSpec String

    {- | The main data storage type (storage of sections).

    PLEASE NOTE: This type is exported only for use by other modules under
    Data.ConfigFile.  You should NEVER access the FiniteMap in a ConfigParser
    directly.  This type may change in future releases of MissingH, which could
    break your programs.  Please retrict yourself to the interface in
    'Data.ConfigFile'.
     -}
    type CPData = Map.Map SectionSpec CPOptions

    {- | Possible ConfigParser errors. -}
    data CPErrorData = ParseError String        -- ^ Parse error
                     | SectionAlreadyExists SectionSpec -- ^ Attempt to create an already-existing ection
                     | NoSection SectionSpec    -- ^ The section does not exist
                     | NoOption OptionSpec      -- ^ The option does not exist
                     | OtherProblem String      -- ^ Miscellaneous error
                     | InterpolationError String -- ^ Raised by 'Data.ConfigFile.interpolatingAccess' if a request was made for a non-existant option
                       deriving (CPErrorData -> CPErrorData -> Bool
    (CPErrorData -> CPErrorData -> Bool)
    -> (CPErrorData -> CPErrorData -> Bool) -> Eq CPErrorData
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: CPErrorData -> CPErrorData -> Bool
    $c/= :: CPErrorData -> CPErrorData -> Bool
    == :: CPErrorData -> CPErrorData -> Bool
    $c== :: CPErrorData -> CPErrorData -> Bool
    Eq, Eq CPErrorData
    Eq CPErrorData =>
    (CPErrorData -> CPErrorData -> Ordering)
    -> (CPErrorData -> CPErrorData -> Bool)
    -> (CPErrorData -> CPErrorData -> Bool)
    -> (CPErrorData -> CPErrorData -> Bool)
    -> (CPErrorData -> CPErrorData -> Bool)
    -> (CPErrorData -> CPErrorData -> CPErrorData)
    -> (CPErrorData -> CPErrorData -> CPErrorData)
    -> Ord CPErrorData
    CPErrorData -> CPErrorData -> Bool
    CPErrorData -> CPErrorData -> Ordering
    CPErrorData -> CPErrorData -> CPErrorData
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: CPErrorData -> CPErrorData -> CPErrorData
    $cmin :: CPErrorData -> CPErrorData -> CPErrorData
    max :: CPErrorData -> CPErrorData -> CPErrorData
    $cmax :: CPErrorData -> CPErrorData -> CPErrorData
    >= :: CPErrorData -> CPErrorData -> Bool
    $c>= :: CPErrorData -> CPErrorData -> Bool
    > :: CPErrorData -> CPErrorData -> Bool
    $c> :: CPErrorData -> CPErrorData -> Bool
    <= :: CPErrorData -> CPErrorData -> Bool
    $c<= :: CPErrorData -> CPErrorData -> Bool
    < :: CPErrorData -> CPErrorData -> Bool
    $c< :: CPErrorData -> CPErrorData -> Bool
    compare :: CPErrorData -> CPErrorData -> Ordering
    $ccompare :: CPErrorData -> CPErrorData -> Ordering
    $cp1Ord :: Eq CPErrorData
    Ord, Int -> CPErrorData -> ShowS
    [CPErrorData] -> ShowS
    CPErrorData -> String
    (Int -> CPErrorData -> ShowS)
    -> (CPErrorData -> String)
    -> ([CPErrorData] -> ShowS)
    -> Show CPErrorData
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [CPErrorData] -> ShowS
    $cshowList :: [CPErrorData] -> ShowS
    show :: CPErrorData -> String
    $cshow :: CPErrorData -> String
    showsPrec :: Int -> CPErrorData -> ShowS
    $cshowsPrec :: Int -> CPErrorData -> ShowS
    Show)

    {- | Indicates an error occurred.  The String is an explanation of the location
    of the error. -}
    type CPError = (CPErrorData, String)

    instance Error CPError where
        noMsg :: CPError
    noMsg = (String -> CPErrorData
    OtherProblem "", "")
        strMsg :: String -> CPError
    strMsg x :: String
    x = (String -> CPErrorData
    OtherProblem String
    x, "")

    {- Removed due to Hugs incompatibility.

    | Basic ConfigParser error handling.  The Left value indicates
    an error, while a Right value indicates success.
    type CPResult a = MonadError CPError m => m a
    -}

    {- | This is the main record that is used by 'Data.ConfigFile'.
    -}
    data ConfigParser = ConfigParser
        { -- | The data itself
          ConfigParser -> CPData
    content :: CPData,
          -- | How to transform an option into a standard representation
          ConfigParser -> ShowS
    optionxform :: (OptionSpec -> OptionSpec),
          -- | Function to look up an option, considering a default value
          -- if 'usedefault' is True; or ignoring a default value otherwise.
          -- The option specification is assumed to be already transformed.
          ConfigParser
    -> ConfigParser -> String -> String -> Either CPError String
    defaulthandler :: ConfigParser -> SectionSpec -> OptionSpec -> Either CPError String,
          -- | Whether or not to seek out a default action when no match
          -- is found.
          ConfigParser -> Bool
    usedefault :: Bool,
          -- | Function that is used to perform lookups, do optional
          -- interpolation, etc.  It is assumed that accessfunc
          -- will internally call defaulthandler to do the underlying lookup.
          -- The option value is not assumed to be transformed.
          ConfigParser
    -> ConfigParser -> String -> String -> Either CPError String
    accessfunc :: (ConfigParser -> SectionSpec -> OptionSpec -> Either CPError String)
        }