-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Configuration Loader
--   
--   Configuration Loader for Production in Haskell
@package salak
@version 0.1.8


-- | Configuration Loader for Production in Haskell.
module Data.Salak

-- | Monad to Load Properties
type LoadProperties = StateT Properties

-- | Load Properties
runLoad :: Monad m => LoadProperties m a -> m Properties

-- | Get current Properties
askProperties :: Monad m => LoadProperties m Properties

-- | Set value to current properties
setValue :: Monad m => Text -> Property -> LoadProperties m ()

-- | Load Properties from CommandLine
loadCommandLine :: MonadIO m => ParseCommandLine -> LoadProperties m ()

-- | Load Properties from CommandLine
loadEnvironment :: MonadIO m => LoadProperties m ()

-- | Load Properties from JSON Value
loadJSON :: MonadIO m => Value -> LoadProperties m ()

-- | Load Properties from Yaml
loadYaml :: MonadIO m => FilePath -> LoadProperties m ()

-- | Load Properties from Yaml if exists
loadYamlIfExists :: MonadIO m => Maybe FilePath -> LoadProperties m ()

-- | Initialize default properties from <tt>CommandLine</tt> and
--   <tt>Environment</tt>. <tt>CommandLine</tt> use default parser.
defaultProperties :: IO Properties

-- | Initialize default properties from <tt>CommandLine</tt> and
--   <tt>Environment</tt>.
defaultProperties' :: ParseCommandLine -> IO Properties

-- | Initialize default properties from <tt>CommandLine</tt>,
--   <tt>Environment</tt> and <tt>Yaml</tt> files. All these configuration
--   sources has orders, from highest order to lowest order:
--   
--   <pre>
--   1. CommandLine
--   2. Environment
--   3. Specified Yaml file(file in "salak.config.dir")
--   4. Yaml file in current directory
--   5. Yaml file in home directory
--   </pre>
defaultPropertiesWithFile :: FileName -> IO Properties

-- | Initialize default properties from <tt>CommandLine</tt>,
--   <tt>Environment</tt> and <tt>Yaml</tt> files. All these configuration
--   sources has orders, from highest order to lowest order:
--   
--   <pre>
--   1. CommandLine
--   2. Environment
--   3. Specified Yaml file(file in "salak.config.dir")
--   4. Yaml file in current directory
--   5. Yaml file in home directory
--   </pre>
defaultPropertiesWithFile' :: FileName -> ParseCommandLine -> IO Properties

-- | The empty <a>Properties</a>
empty :: Properties

-- | Find <a>Properties</a> by key and convert to specific Haskell value.
lookup :: FromProperties a => Text -> Properties -> Return a

-- | Split origin key by <a>.</a> to sub keys:
--   
--   <pre>
--   "salak.config.name" -&gt; ["salak","config","name"]
--   "" -&gt; []
--   "a..b" -&gt; ["a","b"]
--   </pre>
toKeys :: Text -> [Key]

-- | A Property value represented as a Haskell value.
data Property

-- | Numeric Property
PNum :: !Scientific -> Property

-- | String Property
PStr :: !Text -> Property

-- | Bool Property
PBool :: !Bool -> Property

-- | A Property Container to hold all properties
data Properties
Properties :: [Property] -> [HashMap Key Properties] -> Properties

-- | Convert <a>Properties</a> to Haskell value.
class FromProperties a
fromProperties :: FromProperties a => Properties -> Return a

-- | Return of <a>FromProperties</a>
type Return = Either ErrResult

-- | Insert simple <a>Property</a> into <a>Properties</a> by <a>Key</a>. If
--   the key already have values then the new property will discard.
insert :: [Key] -> Property -> Properties -> Properties

-- | Default command line parsers. Use format:
--   
--   <pre>
--   --KEY=VALUE
--   </pre>
--   
--   For example:
--   
--   <pre>
--   --salak.config.name=test.yml =&gt; ("salak.config.name", PStr "test.yml")
--   </pre>
defaultParseCommandLine :: ParseCommandLine

-- | CommandLine parser. Parse command line into property key values.
type ParseCommandLine = [String] -> IO [(String, Property)]

-- | Yaml file name.
type FileName = String

-- | Find <a>Properties</a> by key and convert to specific Haskell value.
(.?>) :: FromProperties a => Properties -> Text -> Return a
infixl 5 .?>

-- | Get property or use default value if not found, but will throw
--   exception if parse failed.
(.|=) :: Return a -> a -> a
infixl 5 .|=

-- | Use default value if Key not found
(.?=) :: Return a -> a -> Return a
infixl 5 .?=

-- | Find <a>Properties</a> by key and convert to specific Haskell value.
--   Throw error if property not found or parse failed
(.>>) :: FromProperties a => Properties -> Text -> a
infixl 5 .>>
type LoaderT = StateT Loader

-- | Load default properties
load :: (FromProperties a, MonadIO m, Show a) => Text -> LoaderT m (IO a)

-- | Run loader
runLoader :: MonadIO m => Properties -> LoaderT m a -> m a

-- | Ask properties setter.
askSetProperties :: MonadIO m => LoaderT m (Properties -> m ())
