-- 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.0


-- | 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 Data.Functor.Alt.Alt 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


-- | 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 Data.Semigroup.Semigroup a => Data.Semigroup.Semigroup (Config.Schema.Docs.DocBuilder a)
instance (Data.Semigroup.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
