-- 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 define schemas for use when loading
--   configuration files using the config-value format. These schemas can
--   be used to process a configuration file into a Haskell value or to
--   automatically generate documentation for the file format.
@package config-schema
@version 1.3.0.0


-- | This module defines the syntax of value specifications.
--   
--   Specifications can be defined using <a>Config.Schema.Spec</a> and can
--   be consumed with <a>Config.Schema.Load</a> and
--   <a>Config.Schema.Doc</a>.
--   
--   This module defines high-level <a>ValueSpec</a> and
--   <tt>SectionsSpec</tt> types that are intended to be used by normal
--   library users. This types are implemented in terms of primitive
--   <a>PrimValueSpec</a> and <a>PrimSectionSpec</a> types. These
--   primitives are what consumers of specifications will need to use.
module Config.Schema.Types

-- | Non-empty disjunction of value specifications. This type is the
--   primary way to specify expected values.
--   
--   Multiple specifications can be combined using this type's <a>Alt</a>
--   instance.
--   
--   To create <a>ValueSpec</a> values see <a>Config.Schema.Spec</a>
data ValueSpec a

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

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

-- | Matches numbers
[NumberSpec] :: PrimValueSpec Number

-- | Matches any atom
[AtomSpec] :: PrimValueSpec Text

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

-- | Documentation identifier and sections specification
[SectionsSpec] :: Text -> SectionsSpec a -> PrimValueSpec a

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

-- | Documentation text and underlying specification. This specification
--   will match values where the underlying specification returns a
--   <a>Right</a> value. Otherwise a <a>Left</a> should contain a short
--   failure explanation.
[CustomSpec] :: Text -> ValueSpec (Either Text a) -> PrimValueSpec a

-- | Label used to hide complex specifications in documentation.
[NamedSpec] :: Text -> ValueSpec a -> PrimValueSpec a

-- | Specific value to be matched
[ExactSpec] :: Value () -> PrimValueSpec ()

-- | Lift a primitive value specification to <a>ValueSpec</a>.
primValueSpec :: PrimValueSpec a -> ValueSpec 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>Alt</a> instance.
runValueSpec :: Alt f => (forall x. PrimValueSpec x -> f x) -> ValueSpec 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.
runValueSpec_ :: Semigroup m => (forall x. PrimValueSpec x -> m) -> ValueSpec a -> m

-- | 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.
--   
--   To create <tt>SectionsSpec</tt> values see <a>Config.Schema.Spec</a>
data SectionsSpec a

-- | 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 PrimSectionSpec :: * -> *

-- | Required section: Name, Documentation, Specification
[ReqSection] :: Text -> Text -> ValueSpec a -> PrimSectionSpec a

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

-- | Lift a single specification into a list of specifications.
primSectionsSpec :: PrimSectionSpec a -> SectionsSpec 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. PrimSectionSpec x -> f x) -> SectionsSpec 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. PrimSectionSpec x -> m) -> SectionsSpec a -> m
instance GHC.Base.Functor Config.Schema.Types.ValueSpec
instance GHC.Base.Applicative Config.Schema.Types.SectionsSpec
instance GHC.Base.Functor Config.Schema.Types.SectionsSpec
instance Data.Functor.Alt.Alt Config.Schema.Types.ValueSpec


-- | This module provides a set of types and operations for defining
--   configuration file schemas.
--   
--   These specifications are can 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 <tt>Client.Configuration</tt> and
--   <tt>Client.Configuration.Colors</tt> modules.
module Config.Schema.Spec

-- | Non-empty disjunction of value specifications. This type is the
--   primary way to specify expected values.
--   
--   Multiple specifications can be combined using this type's <a>Alt</a>
--   instance.
--   
--   To create <a>ValueSpec</a> values see <a>Config.Schema.Spec</a>
data ValueSpec 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 -> ValueSpec a -> (a -> Either Text b) -> ValueSpec b

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

-- | Match an exact value. This can be used to match a specific text
--   literal number literal, atom, list of exact things, etc.
exactSpec :: Value () -> ValueSpec ()

-- | Class of value specifications without parameters.
class HasSpec a
anySpec :: HasSpec a => ValueSpec 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 -> SectionsSpec a -> ValueSpec 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 :: ValueSpec a -> ValueSpec [(Text, a)]

-- | Primitive specification for matching any number.
numberSpec :: ValueSpec Number

-- | Specification for matching any integral number.
integerSpec :: ValueSpec Integer

-- | Specification for matching any number as a <a>Rational</a>.
rationalSpec :: ValueSpec Rational

-- | Specification for matching any non-negative, integral number
naturalSpec :: ValueSpec Natural

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

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

-- | Specification for matching any text literal
textSpec :: ValueSpec Text

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

-- | Primitive specification for matching a particular atom.
atomSpec :: Text -> ValueSpec ()

-- | Primitive specification for matching any atom. Matched atom is
--   returned.
anyAtomSpec :: ValueSpec Text

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

-- | Specification for using atoms <tt>true</tt> and <tt>false</tt> to
--   represent booleans <a>True</a> and <a>False</a> respectively.
trueOrFalseSpec :: ValueSpec Bool

-- | Primitive specification for matching a list of values each satisfying
--   a given element specification.
listSpec :: ValueSpec a -> ValueSpec [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 :: ValueSpec a -> ValueSpec [a]

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

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

-- | 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.
--   
--   To create <tt>SectionsSpec</tt> values see <a>Config.Schema.Spec</a>
data SectionsSpec a

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

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

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

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

-- | Laws:
--   
--   <pre>
--   &lt;!&gt; is associative:             (a &lt;!&gt; b) &lt;!&gt; c = a &lt;!&gt; (b &lt;!&gt; c)
--   &lt;$&gt; left-distributes over &lt;!&gt;:  f &lt;$&gt; (a &lt;!&gt; b) = (f &lt;$&gt; a) &lt;!&gt; (f &lt;$&gt; b)
--   </pre>
--   
--   If extended to an <a>Alternative</a> then <a>&lt;!&gt;</a> should
--   equal <a>&lt;|&gt;</a>.
--   
--   Ideally, an instance of <a>Alt</a> also satisfies the "left
--   distribution" law of MonadPlus with respect to <a>&lt;.&gt;</a>:
--   
--   <pre>
--   &lt;.&gt; right-distributes over &lt;!&gt;: (a &lt;!&gt; b) &lt;.&gt; c = (a &lt;.&gt; c) &lt;!&gt; (b &lt;.&gt; c)
--   </pre>
--   
--   <a>IO</a>, <tt><a>Either</a> a</tt>, <tt><a>ExceptT</a> e m</tt> and
--   <a>STM</a> instead satisfy the "left catch" law:
--   
--   <pre>
--   pure a &lt;!&gt; b = pure a
--   </pre>
--   
--   <a>Maybe</a> and <a>Identity</a> satisfy both "left distribution" and
--   "left catch".
--   
--   These variations cannot be stated purely in terms of the dependencies
--   of <a>Alt</a>.
--   
--   When and if MonadPlus is successfully refactored, this class should
--   also be refactored to remove these instances.
--   
--   The right distributive law should extend in the cases where the a
--   <tt>Bind</tt> or <a>Monad</a> is provided to yield variations of the
--   right distributive law:
--   
--   <pre>
--   (m &lt;!&gt; n) &gt;&gt;- f = (m &gt;&gt;- f) &lt;!&gt; (m &gt;&gt;- f)
--   (m &lt;!&gt; n) &gt;&gt;= f = (m &gt;&gt;= f) &lt;!&gt; (m &gt;&gt;= f)
--   </pre>
class Functor f => Alt (f :: Type -> Type)

-- | <a>&lt;|&gt;</a> without a required <tt>empty</tt>
(<!>) :: Alt f => f a -> f a -> f a
some :: (Alt f, Applicative f) => f a -> f [a]
many :: (Alt f, Applicative f) => f a -> f [a]
infixl 3 <!>
instance Config.Schema.Spec.HasSpec Data.Text.Internal.Text
instance Config.Schema.Spec.HasSpec GHC.Num.Integer.Integer
instance Config.Schema.Spec.HasSpec GHC.Types.Int
instance Config.Schema.Spec.HasSpec GHC.Int.Int8
instance Config.Schema.Spec.HasSpec GHC.Int.Int16
instance Config.Schema.Spec.HasSpec GHC.Int.Int32
instance Config.Schema.Spec.HasSpec GHC.Int.Int64
instance Config.Schema.Spec.HasSpec GHC.Types.Word
instance Config.Schema.Spec.HasSpec GHC.Word.Word8
instance Config.Schema.Spec.HasSpec GHC.Word.Word16
instance Config.Schema.Spec.HasSpec GHC.Word.Word32
instance Config.Schema.Spec.HasSpec GHC.Word.Word64
instance Config.Schema.Spec.HasSpec GHC.Num.Natural.Natural
instance Config.Schema.Spec.HasSpec GHC.Types.Double
instance Config.Schema.Spec.HasSpec GHC.Types.Float
instance GHC.Real.Integral a => Config.Schema.Spec.HasSpec (GHC.Real.Ratio a)
instance Config.Schema.Spec.HasSpec a => Config.Schema.Spec.HasSpec [a]
instance Config.Schema.Spec.HasSpec a => Config.Schema.Spec.HasSpec (GHC.Base.NonEmpty a)
instance (Config.Schema.Spec.HasSpec a, Config.Schema.Spec.HasSpec b) => Config.Schema.Spec.HasSpec (Data.Either.Either a b)


-- | This module provides a complete skeleton of the failures that occurred
--   when trying to match a <a>Value</a> against a <a>ValueSpec</a>
--   allowing custom error rendering to be implemented.
--   
--   The structure is you get a single value and a list of one-or-more
--   primitive specifications that it failed to match along with an
--   enumeration of why that specification failed to match. Some failures
--   are due to failures in nested specifications, so the whole error
--   structure can form a tree.
module Config.Schema.Load.Error

-- | Newtype wrapper for schema load errors.
data ValueSpecMismatch p

-- | Problem value and list of specification failures
ValueSpecMismatch :: p -> Text -> NonEmpty (PrimMismatch p) -> ValueSpecMismatch p

-- | 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 PrimMismatch p

-- | spec description and problem
PrimMismatch :: Text -> Problem p -> PrimMismatch p

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

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

-- | unused section names
UnusedSections :: NonEmpty Text -> Problem p

-- | nested error in given section
SubkeyProblem :: Text -> ValueSpecMismatch p -> Problem p

-- | nested error in given list element
ListElementProblem :: Int -> ValueSpecMismatch p -> Problem p

-- | generic nested error
NestedProblem :: ValueSpecMismatch p -> Problem p

-- | value and spec type mismatch
TypeMismatch :: Problem p

-- | custom spec error message
CustomProblem :: Text -> Problem p

-- | values didn't match
WrongExact :: Problem p

-- | Class for rendering position annotations within the
--   <a>prettyValueSpecMismatch</a>
class (Typeable a, Show a) => ErrorAnnotation a
displayAnnotation :: ErrorAnnotation a => a -> Doc

-- | Pretty-printer for <a>ValueSpecMismatch</a> showing the position and
--   type of value that failed to match along with details about each
--   specification that it didn't match.
prettyValueSpecMismatch :: ErrorAnnotation p => ValueSpecMismatch p -> Doc

-- | Pretty-printer for <a>PrimMismatch</a> showing a summary of the
--   primitive specification that didn't match followed by a more detailed
--   error when appropriate.
prettyPrimMismatch :: ErrorAnnotation p => PrimMismatch p -> Doc

-- | Pretty-printer for <a>Problem</a> that generates a summary line as
--   well as a detailed description (depending on the error)
prettyProblem :: ErrorAnnotation p => Problem p -> (Doc, Doc)

-- | Describe outermost shape of a <a>PrimValueSpec</a>
describeSpec :: PrimValueSpec a -> Text

-- | Describe outermost shape of a <a>Value</a>
describeValue :: Value p -> Text

-- | Simplify a <a>ValueSpecMismatch</a> by collapsing long nested error
--   cases and by assuming that if a type matched that the other mismatched
--   type alternatives are uninteresting. This is used in the
--   implementation of <a>displayException</a>.
simplifyValueSpecMismatch :: ValueSpecMismatch p -> ValueSpecMismatch p
instance GHC.Show.Show p => GHC.Show.Show (Config.Schema.Load.Error.PrimMismatch p)
instance GHC.Show.Show p => GHC.Show.Show (Config.Schema.Load.Error.ValueSpecMismatch p)
instance GHC.Show.Show p => GHC.Show.Show (Config.Schema.Load.Error.Problem p)
instance Config.Schema.Load.Error.ErrorAnnotation Config.Tokens.Position
instance Config.Schema.Load.Error.ErrorAnnotation Config.Macro.FilePosition
instance Config.Schema.Load.Error.ErrorAnnotation ()
instance Config.Schema.Load.Error.ErrorAnnotation p => GHC.Exception.Type.Exception (Config.Schema.Load.Error.ValueSpecMismatch p)


-- | 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>ValueSpec</a> and return either the
--   interpretation of that value or the list of errors encountered.
loadValue :: ValueSpec a -> Value p -> Either (ValueSpecMismatch 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>ValueSpecMismatch</a>
loadValueFromFile :: ValueSpec a -> FilePath -> IO a

-- | Newtype wrapper for schema load errors.
data ValueSpecMismatch p

-- | Problem value and list of specification failures
ValueSpecMismatch :: p -> Text -> NonEmpty (PrimMismatch p) -> ValueSpecMismatch p

-- | 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 PrimMismatch p

-- | spec description and problem
PrimMismatch :: Text -> Problem p -> PrimMismatch p

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

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

-- | unused section names
UnusedSections :: NonEmpty Text -> Problem p

-- | nested error in given section
SubkeyProblem :: Text -> ValueSpecMismatch p -> Problem p

-- | nested error in given list element
ListElementProblem :: Int -> ValueSpecMismatch p -> Problem p

-- | generic nested error
NestedProblem :: ValueSpecMismatch p -> Problem p

-- | value and spec type mismatch
TypeMismatch :: Problem p

-- | custom spec error message
CustomProblem :: Text -> Problem p

-- | values didn't match
WrongExact :: Problem 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 :: ValueSpec (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 :: ValueSpec 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
