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

This module parses TOML into semantically meaningful values.

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 (FromTable (fromTable), runMatcher, Result(..))
import Toml.Lexer (scanTokens, Token(TokError))
import Toml.Located (Located(Located))
import Toml.Parser (parseRawToml)
import Toml.Position (Position(posColumn, posLine))
import Toml.Pretty (TomlDoc, DocClass(..), prettyToken, prettyToml)
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 [Located Token] -> Either (Located Token) [Expr]
parseRawToml (String -> [Located Token]
scanTokens String
str) of
        Left (Located Position
p (TokError String
e)) ->
            forall a b. a -> Either a b
Left (forall r. PrintfType r => String -> r
printf String
"%d:%d: lexical error: %s" (Position -> Int
posLine Position
p) (Position -> Int
posColumn Position
p) String
e)
        Left (Located Position
p Token
t) ->
            forall a b. a -> Either a b
Left (forall r. PrintfType r => String -> r
printf String
"%d:%d: parse error: unexpected %s" (Position -> Int
posLine Position
p) (Position -> Int
posColumn Position
p) (Token -> String
prettyToken Token
t))
        Right [Expr]
exprs -> [Expr] -> Either String Table
semantics [Expr]
exprs

-- | Use the 'FromTable' instance to decode a value from a TOML string.
decode :: FromTable a => String -> Result a
decode :: forall a. FromTable a => String -> Result a
decode = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. String -> Result a
Failure (forall a. Matcher a -> Result a
runMatcher forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromTable a => Table -> Matcher a
fromTable) forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String Table
parse

-- | 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