-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Schema definitions for the config-value package
--   
--   This package makes it possible to defined schemas for use when loading
--   configuration files using the config-value format. These schemas can
--   be used to be process a configuration file into a Haskell value, or to
--   automatically generate documentation for the file format.
@package config-schema
@version 0.5.0.1


-- | This module provides a set of types and operations for defining
--   configuration file schemas. These schemas can be built up using
--   <a>Applicative</a> operations.
--   
--   These specifications are suitable for be consumed by
--   <a>Config.Schema.Load</a> and <a>Config.Schema.Docs</a>.
--   
--   This is the schema system used by the <tt>glirc</tt> IRC client
--   <a>https://hackage.haskell.org/package/glirc</a>. For a significant
--   example, visit the <a>Client.Configuration</a> and
--   <a>Client.Configuration.Colors</a> modules.
module Config.Schema.Spec

-- | A list of section specifications used to process a whole group of
--   key-value pairs. Multiple section specifications can be combined using
--   this type's <a>Applicative</a> instance.
data SectionSpecs a

-- | Specification for a required section with an implicit value
--   specification.
reqSection :: Spec a => Text -> Text -> SectionSpecs a

-- | Specification for an optional section with an implicit value
--   specification.
optSection :: Spec a => Text -> Text -> SectionSpecs (Maybe a)

-- | Specification for a required section with an explicit value
--   specification.
reqSection' :: Text -> ValueSpecs a -> Text -> SectionSpecs a

-- | Specification for an optional section with an explicit value
--   specification.
optSection' :: Text -> ValueSpecs a -> Text -> SectionSpecs (Maybe a)

-- | Non-empty disjunction of value specifications. This type is the
--   primary way to specify expected values. Use the <a>Spec</a> class to
--   generate <a>ValueSpecs</a> for simple types.
--   
--   Multiple specifications can be combined using this type's <a>Alt</a>
--   instance.
data ValueSpecs a

-- | Class of value specifications that don't require arguments.
class Spec a
valuesSpec :: Spec a => ValueSpecs a

-- | Named subsection value specification. The unique identifier will be
--   used for generating a documentation section for this specification and
--   should be unique within the scope of the specification being built.
sectionsSpec :: Text -> SectionSpecs a -> ValueSpecs a

-- | Specification for a section list where the keys are user-defined.
--   Values are matched against the underlying specification and returned
--   as a list of section-name/value pairs.
assocSpec :: ValueSpecs a -> ValueSpecs [(Text, a)]

-- | Specification for matching a particular atom.
atomSpec :: Text -> ValueSpecs ()

-- | Specification for matching any atom. Matched atom is returned.
anyAtomSpec :: ValueSpecs Text

-- | Specification for matching a list of values each satisfying a given
--   element specification.
listSpec :: ValueSpecs a -> ValueSpecs [a]

-- | The custom specification allows an arbitrary function to be used to
--   validate the value extracted by a specification. If <a>Nothing</a> is
--   returned the value is considered to have failed validation.
customSpec :: Text -> ValueSpecs a -> (a -> Maybe b) -> ValueSpecs b

-- | Named value specification. This is useful for factoring complicated
--   value specifications out in the documentation to avoid repetition of
--   complex specifications.
namedSpec :: Text -> ValueSpecs a -> ValueSpecs a

-- | Specification that matches either a single element or multiple
--   elements in a list. This can be convenient for allowing the user to
--   avoid having to specify singleton lists in the configuration file.
oneOrList :: ValueSpecs a -> ValueSpecs [a]

-- | Specification for using <tt>yes</tt> and <tt>no</tt> to represent
--   booleans <a>True</a> and <a>False</a> respectively
yesOrNoSpec :: ValueSpecs Bool

-- | Specification for matching any text as a <a>String</a>
stringSpec :: ValueSpecs String

-- | Specification for matching any integral number.
numSpec :: Num a => ValueSpecs a

-- | Specification for matching any fractional number.
fractionalSpec :: Fractional a => ValueSpecs a

-- | Matches a non-empty list.
nonemptySpec :: ValueSpecs a -> ValueSpecs (NonEmpty a)

-- | Matches a single element or a non-empty list.
oneOrNonemptySpec :: ValueSpecs a -> ValueSpecs (NonEmpty a)

-- | Given an function that handles a single, primitive section
--   specification; <a>runSections</a> will generate one that processes a
--   whole <tt>SectionsSpec</tt>.
--   
--   The results from each section will be sequence together using the
--   <a>Applicative</a> instance in of the result type, and the results can
--   be indexed by the type parameter of the specification.
--   
--   For an example use of <a>runSections</a>, see
--   <a>Config.Schema.Load</a>.
runSections :: Applicative f => (forall x. SectionSpec x -> f x) -> SectionSpecs a -> f a

-- | Given an function that handles a single, primitive section
--   specification; <a>runSections_</a> will generate one that processes a
--   whole <tt>SectionsSpec</tt>.
--   
--   The results from each section will be sequence together using the
--   <a>Monoid</a> instance in of the result type, and the results will not
--   be indexed by the type parameter of the specifications.
--   
--   For an example use of <a>runSections_</a>, see
--   <a>Config.Schema.Docs</a>.
runSections_ :: Monoid m => (forall x. SectionSpec x -> m) -> SectionSpecs a -> m

-- | Given an interpretation of a primitive value specification, extract a
--   list of the possible interpretations of a disjunction of value
--   specifications. Each of these primitive interpretations will be
--   combined using the provided <a>Alt</a> instance.
runValueSpecs :: Alt f => (forall x. ValueSpec x -> f x) -> ValueSpecs a -> f a

-- | Given an interpretation of a primitive value specification, extract a
--   list of the possible interpretations of a disjunction of value
--   specifications. Each of these primitive interpretations will be
--   combined using the provided <a>Semigroup</a> instance.
runValueSpecs_ :: Semigroup m => (forall x. ValueSpec x -> m) -> ValueSpecs a -> m

-- | Specifications for single configuration sections.
--   
--   The fields are section name, documentation text, value specification.
--   Use <a>ReqSection</a> for required key-value pairs and
--   <a>OptSection</a> for optional ones.
data SectionSpec :: * -> *

-- | Required section: Name, Documentation, Specification
[ReqSection] :: Text -> Text -> ValueSpecs a -> SectionSpec a

-- | Optional section: Name, Documentation, Specification
[OptSection] :: Text -> Text -> ValueSpecs a -> SectionSpec (Maybe a)

-- | Lift a single specification into a list of specifications.
liftSectionSpec :: SectionSpec a -> SectionSpecs a

-- | The primitive specification descriptions for values. Specifications
--   built from these primitive cases are found in <a>ValueSpecs</a>.
data ValueSpec :: * -> *

-- | Matches any string literal
[TextSpec] :: ValueSpec Text

-- | Matches integral numbers
[IntegerSpec] :: ValueSpec Integer

-- | Matches any number
[RationalSpec] :: ValueSpec Rational

-- | Matches any atom
[AnyAtomSpec] :: ValueSpec Text

-- | Specific atom to be matched
[AtomSpec] :: Text -> ValueSpec ()

-- | Matches a list of the underlying specification
[ListSpec] :: ValueSpecs a -> ValueSpec [a]

-- | Documentation identifier and section specification
[SectionSpecs] :: Text -> SectionSpecs a -> ValueSpec a

-- | Matches an arbitrary list of sections. Similar to <a>SectionSpec</a>
--   except that that the section names are user-defined.
[AssocSpec] :: ValueSpecs a -> ValueSpec [(Text, a)]

-- | Documentation text, underlying specification
[CustomSpec] :: Text -> ValueSpecs (Maybe a) -> ValueSpec a

-- | Label used to hide complicated specs in documentation
[NamedSpec] :: Text -> ValueSpecs a -> ValueSpec a

-- | Lift a primitive value specification to <a>ValueSpecs</a>.
liftValueSpec :: ValueSpec a -> ValueSpecs a
instance GHC.Base.Applicative Config.Schema.Spec.SectionSpecs
instance GHC.Base.Functor Config.Schema.Spec.SectionSpecs
instance GHC.Base.Functor Config.Schema.Spec.ValueSpecs
instance Config.Schema.Spec.Spec Data.Text.Internal.Text
instance Config.Schema.Spec.Spec GHC.Integer.Type.Integer
instance Config.Schema.Spec.Spec GHC.Real.Rational
instance Config.Schema.Spec.Spec a => Config.Schema.Spec.Spec [a]
instance (Config.Schema.Spec.Spec a, Config.Schema.Spec.Spec b) => Config.Schema.Spec.Spec (Data.Either.Either a b)
instance Config.Schema.Spec.Spec GHC.Types.Int
instance Config.Schema.Spec.Spec GHC.Int.Int8
instance Config.Schema.Spec.Spec GHC.Int.Int16
instance Config.Schema.Spec.Spec GHC.Int.Int32
instance Config.Schema.Spec.Spec GHC.Int.Int64
instance Config.Schema.Spec.Spec GHC.Types.Word
instance Config.Schema.Spec.Spec GHC.Word.Word8
instance Config.Schema.Spec.Spec GHC.Word.Word16
instance Config.Schema.Spec.Spec GHC.Word.Word32
instance Config.Schema.Spec.Spec GHC.Word.Word64
instance Data.Functor.Alt.Alt Config.Schema.Spec.ValueSpecs


-- | This module automates the extraction of a decoded value from a
--   configuration value according to a specification as built using
--   <a>Config.Schema.Spec</a>.
module Config.Schema.Load

-- | Match a <a>Value</a> against a <a>ValueSpecs</a> and return either the
--   interpretation of that value or the list of errors encountered.
loadValue :: ValueSpecs a -> Value p -> Either (NonEmpty (LoadError p)) a

-- | Read a configuration file, parse it, and validate it according to the
--   given specification.
--   
--   Throws <a>IOError</a>, <a>ParseError</a>, or <a>SchemaError</a>
loadValueFromFile :: ValueSpecs a -> FilePath -> IO a

-- | Newtype wrapper for schema load errors.
newtype SchemaError
SchemaError :: (NonEmpty (LoadError Position)) -> SchemaError

-- | Type for errors that can be encountered while decoding a value
--   according to a specification. The error includes a key path indicating
--   where in the configuration file the error occurred.
data LoadError p

-- | position, path, problem
LoadError :: p -> [Text] -> Problem -> LoadError p

-- | Problems that can be encountered when matching a <a>Value</a> against
--   a <a>ValueSpecs</a>.
data Problem

-- | missing section name
MissingSection :: Text -> Problem

-- | unused section names
UnusedSection :: Text -> Problem

-- | failed specification name
SpecMismatch :: Text -> Problem
instance GHC.Show.Show Config.Schema.Load.SchemaError
instance GHC.Base.Monad (Config.Schema.Load.Load p)
instance GHC.Base.Applicative (Config.Schema.Load.Load p)
instance GHC.Base.Functor (Config.Schema.Load.Load p)
instance GHC.Show.Show p => GHC.Show.Show (Config.Schema.Load.LoadError p)
instance GHC.Read.Read p => GHC.Read.Read (Config.Schema.Load.LoadError p)
instance GHC.Show.Show Config.Schema.Load.Problem
instance GHC.Read.Read Config.Schema.Load.Problem
instance GHC.Classes.Ord Config.Schema.Load.Problem
instance GHC.Classes.Eq Config.Schema.Load.Problem
instance GHC.Exception.Exception Config.Schema.Load.SchemaError
instance Data.Functor.Alt.Alt (Config.Schema.Load.Load p)


-- | This module generates a simple textual documentation format for a
--   configuration schema. Each subsection and named value specification
--   will generate it's own top-level component in the documentation.
--   
--   This module is only one of the ways one could generate documentation
--   for a particular configuration specification. All of the defintions
--   would would need to be able to generate another form are exported by
--   <a>Config.Schema.Spec</a>.
--   
--   <pre>
--   configSpec :: ValueSpecs (Text,Maybe Int)
--   configSpec = sectionsSpec ""
--              $ liftA2 (,)
--                  (reqSection "username" "Name used to login")
--                  (optSection "attempts" "Number of login attempts")
--   
--   generateDocs configSpec
--   
--   -- Top-level configuration file fields:
--   --     username: REQUIRED text
--   --        Name used to login
--   --     attempts: integer
--   --        Number of login attempts
--   </pre>
module Config.Schema.Docs

-- | Default documentation generator.
generateDocs :: ValueSpecs a -> Doc
instance GHC.Base.Monad Config.Schema.Docs.DocBuilder
instance GHC.Base.Applicative Config.Schema.Docs.DocBuilder
instance GHC.Base.Functor Config.Schema.Docs.DocBuilder
instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Config.Schema.Docs.DocBuilder a)
instance (GHC.Base.Semigroup a, GHC.Base.Monoid a) => GHC.Base.Monoid (Config.Schema.Docs.DocBuilder a)


-- | This package makes it possible to define schemas for configuration
--   files. These schemas can be used to generate a validating
--   configuration file loader, and to produce documentation about the
--   supported format.
--   
--   For documentation on the <a>config-value</a> file format, see the
--   <a>Config</a> module.
--   
--   <a>Config.Schema.Spec</a> provides definitions used to make new
--   schemas.
--   
--   <a>Config.Schema.Load</a> uses schemas to match schemas against
--   configuration values.
--   
--   <a>Config.Schema.Docs</a> generates textual documentation for a
--   schema.
module Config.Schema
