configifier-0.0.4: examples/Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS #-}
module Main
where
import Control.Applicative ((<$>))
import Data.String.Conversions (ST, cs, (<>))
import Data.Typeable (Proxy(Proxy))
import System.Environment (getEnvironment, getArgs)
import Text.Show.Pretty (ppShow)
import qualified Data.ByteString as SBS
import qualified Data.Text.IO as ST
import Data.Configifier
-- * an interesting example
type Cfg = ToConfigCode Cfg'
type Cfg' =
"frontend" :> ServerCfg' :>: "descr"
:*> Maybe ("backend" :> ServerCfg')
:*> "default_users" :> [UserCfg'] :>: "list of users that are created on start if database is empty"
type ServerCfg = ToConfigCode ServerCfg'
type ServerCfg' =
"bind_port" :> Int
:*> "bind_host" :> ST
:*> Maybe ("expose_host" :> ST)
type UserCfg = ToConfigCode UserCfg'
type UserCfg' =
"name" :> ST :>: "user name (must be unique)"
:*> "email" :> ST :>: "email address (must also be unique)"
:*> "password" :> ST :>: "password (not encrypted)"
defaultCfg :: Tagged Cfg
defaultCfg = Tagged $
Id (Id 8001 :*> Id "localhost" :*> JustO (Id "expose"))
:*> JustO (Id (Id 8002 :*> Id "localhost" :*> NothingO))
:*> Id [u1, u2]
where
u1 = Id "ralf" :*> Id "ralf@localhost" :*> Id "gandalf"
u2 = Id "claudi" :*> Id "claudi@remotehost" :*> Id "also_gandalf"
main :: IO ()
main = do
sources <- sequence
[ YamlString <$> SBS.readFile "examples/config.yaml"
, ShellEnv <$> getEnvironment
, CommandLine <$> getArgs
]
ST.putStrLn $ docs (Proxy :: Proxy Cfg) <> "\n\n"
let dump cfg = do
putStrLn $ ppShow cfg
putStrLn . cs . renderConfigFile $ cfg
dump defaultCfg
cfg :: Tagged Cfg <- configify sources
dump cfg
putStrLn "accessing config values:"
print $ (Tagged (cfg >>. (Proxy :: Proxy '["frontend"])) :: Tagged ServerCfg)
print $ cfg >>. (Proxy :: Proxy '["frontend", "expose_host"])
print $ cfg >>. (Proxy :: Proxy '["frontend", "bind_port"])
{-
Example session:
$ configifier-example
[...]
accessing config values:
(Tagged Id 8001 :*> (Id "localhost" :*> JustO (Id "fost")))
Just "fost"
8001
$ FRONTEND_BIND_PORT=31 configifier-example
[...]
accessing config values:
(Tagged Id 31 :*> (Id "localhost" :*> JustO (Id "fost")))
Just "fost"
31
$ FRONTEND_BIND_PORT=31 configifier-example --frontend-bind-port 15
[...]
accessing config values:
(Tagged Id 15 :*> (Id "localhost" :*> JustO (Id "fost")))
Just "fost"
15
$ configifier-example --frontend-expose-host "false"
[...]
configifier-example: CommandLinePrimitiveOtherError (ShellEnvNoParse {shellEnvNoParseType = "Text", shellEnvNoParseValue = "false", shellEnvNoParseMsg = "when expecting a Text, encountered Boolean instead"})
$ configifier-example --frontend-expose-host "\"false\""
[...]
accessing config values:
(Tagged Id 8001 :*> (Id "localhost" :*> JustO (Id "false")))
Just "false"
8001
$ configifier-example --config examples/config2.yaml
[...]
backend:
bind_host: arrr
bind_port: 281
[...]
-}