module Language.Libconfig.Encode (
encode
, encodeAt
, encodeValue
, encodeTo
, valueType
, scalarType
) where
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Maybe
import Control.Monad (guard, replicateM_)
import qualified Data.Text as T (unpack)
import Language.Libconfig.Types
import Language.Libconfig.Bindings (ConfigType(..))
import qualified Language.Libconfig.Bindings as C
valueType :: Value -> ConfigType
valueType (Scalar s) = scalarType s
valueType (Array _) = ArrayType
valueType (List _) = ListType
valueType (Group _) = GroupType
scalarType :: Scalar -> ConfigType
scalarType (Boolean _) = BoolType
scalarType (Integer _) = IntType
scalarType (Hex _) = IntType
scalarType (Integer64 _) = Int64Type
scalarType (Hex64 _) = Int64Type
scalarType (Float _) = FloatType
scalarType (String _) = StringType
scalarSet :: C.Setting -> Scalar -> MaybeT IO ()
scalarSet sp = MaybeT . go
where
go (Boolean b) = C.configSettingSetBool sp b
go (Integer i) = C.configSettingSetInt sp (fromIntegral i)
go (Integer64 i) = C.configSettingSetInt64 sp i
go (Hex h) = C.configSettingSetInt sp (fromIntegral h)
go (Hex64 h) = C.configSettingSetInt64 sp (fromIntegral h)
go (Float f) = C.configSettingSetFloat sp f
go (String s) = C.configSettingSetString sp (T.unpack s)
addValue :: C.Setting -> Value -> MaybeT IO C.Setting
addValue parent value = do
newset <- MaybeT $ C.configSettingAdd parent "" (valueType value)
setValue newset value
return newset
addSetting :: C.Setting -> Setting -> MaybeT IO C.Setting
addSetting parent (name := value) = do
newset <- MaybeT $ C.configSettingAdd parent (T.unpack name) (valueType value)
setValue newset value
return newset
setValue :: C.Setting -> Value -> MaybeT IO ()
setValue sp (Scalar s) = scalarSet sp s
setValue sp (Array a) = mapM_ (addValue sp . Scalar) a
setValue sp (Group g) = mapM_ (addSetting sp) g
setValue sp (List l) = mapM_ (addValue sp) l
encode :: Group -> MaybeT IO C.Configuration
encode g = do
conf <- liftIO C.configInit
encodeAt conf g
return conf
encodeTo :: Group -> String -> MaybeT IO ()
encodeTo g filename = do
c <- encode g
MaybeT $ C.configWriteFile c filename
encodeAt :: C.Configuration -> Group -> MaybeT IO ()
encodeAt conf g = do
root <- MaybeT $ C.configRootSetting conf
setValue root (Group g)
checkType :: C.Setting -> C.ConfigType -> MaybeT IO ()
checkType sp ty = do
ty' <- liftIO $ C.configSettingType sp
guard (ty == ty')
removeKids :: C.Setting -> MaybeT IO ()
removeKids sp = do
count <- liftIO $ C.configSettingLength sp
replicateM_ count (MaybeT $ C.configSettingRemoveElem sp 0)
encodeValue :: C.Setting -> Value -> MaybeT IO ()
encodeValue sp v = do
checkType sp (valueType v)
removeKids sp
setValue sp v