packages feed

config-schema 0.4.0.0 → 0.4.1.0

raw patch · 4 files changed

+61/−2 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Config.Schema.Load: SchemaError :: (NonEmpty (LoadError Position)) -> SchemaError
+ Config.Schema.Load: instance GHC.Exception.Exception Config.Schema.Load.SchemaError
+ Config.Schema.Load: instance GHC.Show.Show Config.Schema.Load.SchemaError
+ Config.Schema.Load: loadValueFromFile :: FilePath -> ValueSpecs a -> IO a
+ Config.Schema.Load: newtype SchemaError

Files

ChangeLog.md view
@@ -1,5 +1,11 @@ # Revision history for config-schema +## 0.4.1.0++* Add `loadValueFromFile` and `SchemaError`. This is intended+  as a quick way to get a configuration file loaded with all+  errors being thrown as exceptions.+ ## 0.4.0.0  * Parameterize the Load module on a position type
README.md view
@@ -3,6 +3,14 @@  [![Hackage](https://img.shields.io/hackage/v/config-schema.svg)](https://hackage.haskell.org/package/config-schema) [![Build Status](https://secure.travis-ci.org/glguy/config-schema.png?branch=master)](http://travis-ci.org/glguy/config-schema) +Live Demo+--------++The config-value and config-schema packages are available in a [live demo](https://glguy.net/config-demo/).++About+--------+ This package allows the user to define configuration schemas suitable for matching against configuration files written in the [config-value](https://hackage.haskell.org/package/config-value) format.
config-schema.cabal view
@@ -1,5 +1,5 @@ name:                config-schema-version:             0.4.0.0+version:             0.4.1.0 synopsis:            Schema definitions for the config-value package description:         This package makes it possible to defined schemas for use when                      loading configuration files using the config-value format.
src/Config/Schema/Load.hs view
@@ -12,12 +12,15 @@ -} module Config.Schema.Load   ( loadValue+  , loadValueFromFile    -- * Errors+  , SchemaError(..)   , LoadError(..)   , Problem(..)   ) where +import           Control.Exception                (Exception(..), throwIO) import           Control.Monad                    (zipWithM) import           Control.Monad.Trans.Class        (lift) import           Control.Monad.Trans.State        (StateT(..), runStateT)@@ -31,6 +34,7 @@ import qualified Data.List.NonEmpty as NonEmpty import           Data.Text                        (Text) import qualified Data.Text as Text+import qualified Data.Text.IO as Text  import           Config import           Config.Schema.Spec@@ -46,6 +50,47 @@ loadValue spec val = runLoad (getValue spec val)  +-- | Read a configuration file, parse it, and validate it according+-- to the given specification.+--+-- Throws 'IOError', 'ParseError', or 'SchemaError'+loadValueFromFile ::+  FilePath     {- ^ filename      -} ->+  ValueSpecs a {- ^ specification -} ->+  IO a+loadValueFromFile path spec =+  do txt <- Text.readFile path+     val <- either throwIO return (parse txt)+     either (throwIO . SchemaError) return (loadValue spec val)+++-- | Newtype wrapper for schema load errors.+newtype SchemaError = SchemaError (NonEmpty (LoadError Position))+  deriving Show++-- | Custom 'displayException' implementation+instance Exception SchemaError where+  displayException (SchemaError e) = foldr showLoadError "" e+    where+      showLoadError (LoadError pos path problem)+        = shows (posLine pos)+        . showChar ':'+        . shows (posColumn pos)+        . showString ": "+        . foldr (\x xs -> showString (Text.unpack x) . showChar ':' . xs) id path+        . showChar ' '+        . showProblem problem+        . showChar '\n'++      showProblem p =+        case p of+          MissingSection x -> showString "missing required section `"+                            . showString (Text.unpack x) . showChar '`'+          UnusedSection  x -> showString "unused section `"+                            . showString (Text.unpack x) . showChar '`'+          SpecMismatch   x -> showString "expected " . showString (Text.unpack x)++ getSection :: p -> SectionSpec a -> StateT [Section p] (Load p) a getSection pos (ReqSection k _ w) =   do v <- StateT (lookupSection pos k)@@ -102,7 +147,7 @@ -- against the given specification and associates them with the -- section name. getAssoc :: ValueSpecs a -> [Section p] -> Load p [(Text,a)]-getAssoc w = traverse $ \(Section _ k v) -> (,) k <$> getValue w v+getAssoc w = traverse $ \(Section _ k v) -> (,) k <$> scope k (getValue w v)   -- | Match a value against its specification. If 'Just' is matched