-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | parser for config files, shell variables, command line args. -- @package configifier @version 0.0.2 module Data.Configifier -- | the equivalent of record field selectors. data (:>) (s :: Symbol) (t :: *) L :: t -> (:>) -- | descriptive strings for documentation. (the way we use this is still a -- little awkward. use tuple of name string and descr string? or a type -- class "path" with a type family that translates both "" :>: -- "" and "" to ""?) data (:>:) a (s :: Symbol) D :: a -> (:>:) a -- | cons for record fields. data (:|) a b (:|) :: a -> b -> (:|) a b class Entry a b entry :: Entry a b => a -> b data Source ConfigFileYaml :: SBS -> Source ShellEnv :: [(String, String)] -> Source CommandLine :: [String] -> Source data ConfigFile data ShellEnv data CommandLine data Error InvalidJSON :: String -> Error ShellEnvNoParse :: (String, String) -> Error ShellEnvSegmentNotFound :: String -> Error CommandLinePrimitiveParseError :: String -> Error CommandLinePrimitiveOther :: Error -> Error configify :: (FromJSON cfg, HasParseConfigFile cfg, HasParseShellEnv cfg, HasParseCommandLine cfg) => [Source] -> Either Error cfg class HasParseConfigFile cfg parseConfigFile :: HasParseConfigFile cfg => Proxy cfg -> SBS -> Either Error Value type Env = [(String, String)] class HasParseShellEnv a parseShellEnv :: HasParseShellEnv a => Proxy a -> Env -> Either Error Value class HasParseShellEnv' a parseShellEnv' :: HasParseShellEnv' a => Proxy a -> Env -> Either Error Pair -- | since shell env is not ideally suitable for providing arbitrary-length -- lists of sub-configs, we cheat: if a value is fed into a place where a -- list of values is expected, a singleton list is constructed -- implicitly. -- | the sub-object structure of the config file is represented by '_' in -- the shell variable names. (i think it's still ok to have '_' in your -- config variable names instead of caml case; this parser first chops -- off matching names, then worries about trailing '_'.) type Args = [String] class HasParseCommandLine cfg parseCommandLine :: HasParseCommandLine cfg => Proxy cfg -> [String] -> Either Error Value -- | Very basic fist approach: read --(key)(=|s+)(value); -- construct shell env from keys and names, and use parseShellEnv -- on the command line. If it doesn't like the syntax used in the command -- line, it will crash. I hope for this to get much fancier in the -- future. primitiveParseCommandLine :: HasParseShellEnv cfg => Proxy cfg -> [String] -> Either Error Value parseArgs :: Args -> Either String Env parseArgsWithEqSign :: String -> Either String Env parseArgsWithSpace :: String -> String -> Either String Env -- | Type-level lookup of a path in a configuration type. A path is -- represented as a list of symbols. -- | This is <|> on Maybe lifted to the type level. -- | A CMaybe is a static version of Maybe, i.e., we know at -- compile time whether we have Just or Nothing. data CMaybe (a :: Maybe *) CNothing :: CMaybe Nothing CJust :: a -> CMaybe (Just a) -- | This is a version of <|> on Maybe for -- CMaybe. combine :: CMaybe a -> CMaybe b -> CMaybe (OrElse a b) -- | This is a wrapper around sel that hides the interal use of -- CMaybe. As we expect, this version will just cause a type error -- if it is applied to an illegal path. (>.) :: (Sel a p, ValE a p ~ Done r) => a -> Proxy p -> r -- | FIXME: is it possible to remove CMaybe from the signature and -- return Val a p instead? class Sel a p sel :: Sel a p => a -> Proxy p -> CMaybe (Val a p) -- | We need the Val constraint here because overlapping instances -- and closed type families aren't fully compatible. GHC won't be able to -- recognize that we've already excluded the other cases and not reduce -- Val automatically. But the constraint should always resolve, -- unless we've made a mistake, and the worst outcome if we did are extra -- type errors, not run-time errors. data Exc a b Fail :: a -> Exc a b Done :: b -> Exc a b data LookupFailed a p type ValE (a :: *) (p :: [Symbol]) = ToExc (LookupFailed a p) (Val a p) -- | Merge two json trees such that the latter overwrites nodes in the -- former. Null is considered as non-existing. Otherwise, right -- values overwrite left values. (<<>>) :: Value -> Value -> Value merge :: [Value] -> Value mergeAndCatch :: [Either Error Value] -> Either Error Value docs :: (HasToDoc a, HasRenderDoc ConfigFile, HasRenderDoc ShellEnv, HasRenderDoc CommandLine) => Proxy a -> ST data Doc DocDict :: [(String, Maybe String, Doc)] -> Doc DocList :: Doc -> Doc DocBase :: String -> Doc concatDoc :: Doc -> Doc -> Doc class HasToDoc a toDoc :: HasToDoc a => Proxy a -> Doc _makeDocPair :: (KnownSymbol path, KnownSymbol descr, HasToDoc v) => Proxy path -> Maybe (Proxy descr) -> Proxy v -> Doc class HasRenderDoc t renderDoc :: HasRenderDoc t => Proxy t -> Doc -> ST instance [overlap ok] Typeable (:>) instance [overlap ok] Typeable (:>:) instance [overlap ok] Typeable (:|) instance [overlap ok] Typeable Source instance [overlap ok] Typeable Error instance [overlap ok] Typeable Doc instance [overlap ok] Eq t => Eq (s :> t) instance [overlap ok] Ord t => Ord (s :> t) instance [overlap ok] Show t => Show (s :> t) instance [overlap ok] Eq a => Eq (a :>: s) instance [overlap ok] Ord a => Ord (a :>: s) instance [overlap ok] Show a => Show (a :>: s) instance [overlap ok] (Eq a, Eq b) => Eq (a :| b) instance [overlap ok] (Ord a, Ord b) => Ord (a :| b) instance [overlap ok] (Show a, Show b) => Show (a :| b) instance [overlap ok] Eq Source instance [overlap ok] Ord Source instance [overlap ok] Show Source instance [overlap ok] Eq Error instance [overlap ok] Ord Error instance [overlap ok] Show Error instance [overlap ok] Eq Doc instance [overlap ok] Ord Doc instance [overlap ok] Show Doc instance [overlap ok] Read Doc instance [overlap ok] HasRenderDoc CommandLine instance [overlap ok] HasRenderDoc ShellEnv instance [overlap ok] HasRenderDoc ConfigFile instance [overlap ok] HasToDoc Bool instance [overlap ok] HasToDoc Int instance [overlap ok] HasToDoc ST instance [overlap ok] HasToDoc a => HasToDoc [a] instance [overlap ok] (HasToDoc o1, HasToDoc o2) => HasToDoc (o1 :| o2) instance [overlap ok] (KnownSymbol path, KnownSymbol descr, HasToDoc v) => HasToDoc ((path :> v) :>: descr) instance [overlap ok] (KnownSymbol path, HasToDoc v) => HasToDoc (path :> v) instance [overlap ok] Val a ps ~ 'Nothing => Sel a ps instance [overlap ok] (Sel a (p : ps), Sel b (p : ps)) => Sel (a :| b) (p : ps) instance [overlap ok] Sel t ps => Sel (p :> t) (p : ps) instance [overlap ok] Sel a (p : ps) => Sel (a :>: s) (p : ps) instance [overlap ok] Sel a '[] instance [overlap ok] HasParseShellEnv cfg => HasParseCommandLine cfg instance [overlap ok] (KnownSymbol path, KnownSymbol descr, HasParseShellEnv v, HasParseShellEnv o) => HasParseShellEnv (((path :> v) :>: descr) :| o) instance [overlap ok] (KnownSymbol path, KnownSymbol descr, HasParseShellEnv v) => HasParseShellEnv ((path :> v) :>: descr) instance [overlap ok] (KnownSymbol path, HasParseShellEnv v, HasParseShellEnv o) => HasParseShellEnv ((path :> v) :| o) instance [overlap ok] (KnownSymbol path, HasParseShellEnv v) => HasParseShellEnv (path :> v) instance [overlap ok] HasParseShellEnv a => HasParseShellEnv [a] instance [overlap ok] HasParseShellEnv ST instance [overlap ok] HasParseShellEnv Bool instance [overlap ok] HasParseShellEnv Int instance [overlap ok] (KnownSymbol path, KnownSymbol descr, ToJSON v) => ToJSON ((path :> v) :>: descr) instance [overlap ok] (ToJSON o1, ToJSON o2) => ToJSON (o1 :| o2) instance [overlap ok] (KnownSymbol path, ToJSON v) => ToJSON (path :> v) instance [overlap ok] (KnownSymbol path, KnownSymbol descr, FromJSON v) => FromJSON ((path :> v) :>: descr) instance [overlap ok] (FromJSON o1, FromJSON o2) => FromJSON (o1 :| o2) instance [overlap ok] (KnownSymbol path, FromJSON v) => FromJSON (path :> v) instance [overlap ok] HasParseConfigFile cfg instance [overlap ok] Entry a b => Entry a (b :>: s) instance [overlap ok] Entry a b => Entry a (s :> b) instance [overlap ok] a ~ b => Entry a b