module Toml.Parser.TOML ( hasKeyP , tableHeaderP , inlineTableP , tomlP ) where import Control.Applicative (Alternative (many)) import Control.Applicative.Combinators (sepEndBy, between, eitherP) import Toml.Parser.Core (Parser, sc, text) import Toml.Parser.Value (keyP, tableNameP, anyValueP) import Toml.PrefixTree (Key (..), fromList) import Toml.Type (AnyValue, TOML (..)) import qualified Data.HashMap.Lazy as HashMap hasKeyP :: Parser (Key, Either AnyValue TOML) hasKeyP = (,) <$> keyP <* text "=" <*> eitherP anyValueP inlineTableP inlineTableP :: Parser TOML inlineTableP = between (text "{") (text "}") (makeToml <$> hasKeyP `sepEndBy` text ",") tableHeaderP :: Parser (Key, TOML) tableHeaderP = (,) <$> tableNameP <*> (makeToml <$> many hasKeyP) distributeEithers :: [(c, Either a b)] -> ([(c, a)], [(c, b)]) distributeEithers = foldr distribute ([], []) where distribute :: (c, Either a b) -> ([(c, a)], [(c, b)]) -> ([(c, a)], [(c, b)]) distribute (k, Left a) (ls, rs) = ((k, a) : ls, rs) distribute (k, Right b) (ls, rs) = (ls, (k, b) : rs) makeToml :: [(Key, Either AnyValue TOML)] -> TOML makeToml kvs = TOML (HashMap.fromList lefts) (fromList rights) where (lefts, rights) = distributeEithers kvs tomlP :: Parser TOML tomlP = do sc (val, inline) <- distributeEithers <$> many hasKeyP tables <- many tableHeaderP return TOML { tomlPairs = HashMap.fromList val , tomlTables = fromList $ tables ++ inline }