Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/glguy/config-schema
Self-documenting, combinator constructed configuration schemas
https://github.com/glguy/config-schema
configuration haskell schema
Last synced: 3 months ago
JSON representation
Self-documenting, combinator constructed configuration schemas
- Host: GitHub
- URL: https://github.com/glguy/config-schema
- Owner: glguy
- License: isc
- Created: 2017-05-05T20:37:41.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-11-21T16:51:00.000Z (about 1 year ago)
- Last Synced: 2024-05-08T20:13:47.713Z (8 months ago)
- Topics: configuration, haskell, schema
- Language: Haskell
- Homepage:
- Size: 129 KB
- Stars: 7
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: ChangeLog.md
- License: LICENSE
Awesome Lists containing this project
README
config-schema
=============[![Hackage](https://img.shields.io/hackage/v/config-schema.svg)](https://hackage.haskell.org/package/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.
These schemas allow the user to extract an arbitrary Haskell value from
an interpretation of a configuration file. It also allows the user to
programatically generate documentation for the configuration files
accepted by the loader.```haskell
{-# Language OverloadedStrings, ApplicativeDo #-}
module Example whereimport qualified Data.Text as Text
import Data.Text (Text)
import Data.Monoid ((<>))
import Data.Functor.Alt (())
import Data.List.NonEmpty (NonEmpty)import Config
import Config.SchemaexampleFile :: Text
exampleFile =
" name: \"Johny Appleseed\" \n\
\ age : 99 \n\
\ happy: yes \n\
\ kids: \n\
\ * name: \"Bob\" \n\
\ * name: \"Tom\" \n"exampleValue :: Value Position
Right exampleValue = parse exampleFileexampleSpec :: ValueSpec Text
exampleSpec = sectionsSpec "" $
do name <- reqSection "name" "Full name"
age <- reqSection "age" "Age of user"
happy <- optSection' "happy" yesOrNo
"Current happiness status"
kids <- reqSection' "kids" (oneOrList kidSpec)
"All children's names"return $
let happyText = case happy of Just True -> " and is happy"
Just False -> " and is not happy"
Nothing -> " and is private"in name <> " is " <> Text.pack (show (age::Integer)) <>
" years old and has kids " <>
Text.intercalate ", " kids <>
happyTextkidSpec :: ValueSpec Text
kidSpec = sectionsSpec "kid" (reqSection "name" "Kid's name")-- | Matches the 'yes' and 'no' atoms
yesOrNo :: ValueSpec Bool
yesOrNo = True <$ atomSpec "yes"
False <$ atomSpec "no"printDoc :: IO ()
printDoc = print (generateDocs exampleSpec)
-- *Example> printDoc
-- Top-level configuration file fields:
-- name: REQUIRED text
-- Full name
-- age: REQUIRED integer
-- Age of user
-- happy: `yes` or `no`
-- Current happiness status
-- kids: REQUIRED kid or list of kid
-- All children
--
-- kid
-- name: REQUIRED text
-- Kid's nameexample :: Either (NonEmpty (LoadError Position)) Text
example = loadValue exampleSpec exampleValue
-- *Example> exampleVal
-- Right "Johny Appleseed is 99 years old and has kids Bob, Tom and is happy"
```