{-|
Module      : Toml
Description : TOML parsing, printing, and codecs
Copyright   : (c) Eric Mertens, 2023
License     : ISC
Maintainer  : emertens@gmail.com

This is the high-level interface to the toml-parser library.
It enables parsing, printing, and coversion into and out of
application-specific representations.

This parser implements TOML 1.0.0 <https://toml.io/en/v1.0.0>
as carefully as possible.

-}
module Toml (

    -- * Types
    Table,
    Value(..),

    -- * Parsing
    parse,

    -- * Printing
    prettyToml,
    DocClass(..),

    -- * Serialization
    decode,
    encode,
    Result(..),
    ) where

import Toml.FromValue (FromValue (fromValue), Result(..))
import Toml.FromValue.Matcher (runMatcher)
import Toml.Parser (parseRawToml)
import Toml.Pretty (TomlDoc, DocClass(..), prettyToml, prettySemanticError, prettyMatchMessage, prettyLocated)
import Toml.Semantics (semantics)
import Toml.ToValue (ToTable (toTable))
import Toml.Value (Table, Value(..))

-- | Parse a TOML formatted 'String' or report an error message.
parse :: String -> Either String Table
parse :: String -> Either String Table
parse String
str =
    case String -> Either (Located String) [Expr]
parseRawToml String
str of
        Left Located String
e -> String -> Either String Table
forall a b. a -> Either a b
Left (Located String -> String
prettyLocated Located String
e)
        Right [Expr]
exprs ->
            case [Expr] -> Either (Located SemanticError) Table
semantics [Expr]
exprs of
                Left Located SemanticError
e -> String -> Either String Table
forall a b. a -> Either a b
Left (Located String -> String
prettyLocated (SemanticError -> String
prettySemanticError (SemanticError -> String)
-> Located SemanticError -> Located String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Located SemanticError
e))
                Right Table
tab -> Table -> Either String Table
forall a b. b -> Either a b
Right Table
tab

-- | Use the 'FromValue' instance to decode a value from a TOML string.
decode :: FromValue a => String -> Result String a
decode :: forall a. FromValue a => String -> Result String a
decode String
str =
    case String -> Either String Table
parse String
str of
        Left String
e -> [String] -> Result String a
forall e a. [e] -> Result e a
Failure [String
e]
        Right Table
tab ->
            case Matcher a -> Result MatchMessage a
forall a. Matcher a -> Result MatchMessage a
runMatcher (Value -> Matcher a
forall a. FromValue a => Value -> Matcher a
fromValue (Table -> Value
Table Table
tab)) of
                Failure [MatchMessage]
es -> [String] -> Result String a
forall e a. [e] -> Result e a
Failure (MatchMessage -> String
prettyMatchMessage (MatchMessage -> String) -> [MatchMessage] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [MatchMessage]
es)
                Success [MatchMessage]
ws a
x -> [String] -> a -> Result String a
forall e a. [e] -> a -> Result e a
Success (MatchMessage -> String
prettyMatchMessage (MatchMessage -> String) -> [MatchMessage] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [MatchMessage]
ws) a
x

-- | Use the 'ToTable' instance to encode a value to a TOML string.
encode :: ToTable a => a -> TomlDoc
encode :: forall a. ToTable a => a -> TomlDoc
encode = Table -> TomlDoc
prettyToml (Table -> TomlDoc) -> (a -> Table) -> a -> TomlDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Table
forall a. ToTable a => a -> Table
toTable