module Data.Tini.Ops
( empty, get, set, remove, modify
, toList, fromList, merge
) where
import Data.List (foldl')
import Data.Tini.IniValue
import Data.Tini.Types
import Data.Tini.Utils (trim)
empty :: Ini
empty = Ini []
get :: IniValue a => Ini -> Key -> Maybe a
get (Ini ini) (Key s k) = lookup s ini >>= lookup (KeyPart k) >>= readValue
set :: IniValue a => Ini -> Key -> a -> Ini
set ini key val = modify (const (Just (showValue val))) key ini
remove :: Key -> Ini -> Ini
remove = modify (const Nothing)
upd :: Eq k => (Maybe v -> Maybe v) -> k -> [(k, v)] -> [(k, v)]
upd f k xs =
case break ((== k) . fst) xs of
(pre, (_, v):suf) -> pre ++ maybe [] (\v' -> [(k, v')]) (f (Just v)) ++ suf
(_, []) -> xs ++ maybe [] (\v -> [(k, v)]) (f Nothing)
modify :: (Maybe String -> Maybe String) -> Key -> Ini -> Ini
modify f (Key s k) = Ini . upd (Just . upd (fmap clean . f) (KeyPart k) . maybe [] id) s . unIni
where clean = trim . filter (/= '\n')
toList :: Ini -> [(Key, String)]
toList (Ini secs) = [(Key sec k, v) | (sec, ps) <- secs, (KeyPart k, v) <- ps]
fromList :: [(Key, String)] -> Ini
fromList = foldl' (uncurry . set) empty
merge :: Ini -> Ini -> Ini
merge l = foldl' (uncurry . set) l . toList