{-|
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 Text.Printf (printf)
import Toml.FromValue (FromValue (fromValue), Result(..))
import Toml.FromValue.Matcher (runMatcher)
import Toml.Located (Located(Located))
import Toml.Parser (parseRawToml)
import Toml.Position (Position(posColumn, posLine))
import Toml.Pretty (TomlDoc, DocClass(..), prettyToml, prettySemanticError, prettyMatchMessage)
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 Position
p String
e) -> forall a b. a -> Either a b
Left (forall r. PrintfType r => String -> r
printf String
"%d:%d: %s" (Position -> Int
posLine Position
p) (Position -> Int
posColumn Position
p) String
e)
        Right [Expr]
exprs ->
            case [Expr] -> Either (Located SemanticError) Table
semantics [Expr]
exprs of
                Left (Located Position
p SemanticError
e) ->
                    forall a b. a -> Either a b
Left (forall r. PrintfType r => String -> r
printf String
"%d:%d: %s" (Position -> Int
posLine Position
p) (Position -> Int
posColumn Position
p) (SemanticError -> String
prettySemanticError SemanticError
e))
                Right Table
tab -> 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 -> forall e a. [e] -> Result e a
Failure [String
e]
        Right Table
tab ->
            case forall a. Matcher a -> Result MatchMessage a
runMatcher (forall a. FromValue a => Value -> Matcher a
fromValue (Table -> Value
Table Table
tab)) of
                Failure [MatchMessage]
es -> forall e a. [e] -> Result e a
Failure (MatchMessage -> String
prettyMatchMessage forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [MatchMessage]
es)
                Success [MatchMessage]
ws a
x -> forall e a. [e] -> a -> Result e a
Success (MatchMessage -> String
prettyMatchMessage 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToTable a => a -> Table
toTable