{- |
Module                  : Toml.Parser.Key
Copyright               : (c) 2018-2022 Kowainik
SPDX-License-Identifier : MPL-2.0
Maintainer              : Kowainik <xrom.xkov@gmail.com>
Stability               : Stable
Portability             : Portable

Parsers for keys and table names.

@since 1.2.0.0
-}

module Toml.Parser.Key
       ( keyP
       , tableNameP
       , tableArrayNameP
       ) where

import Control.Applicative (Alternative (..))
import Control.Applicative.Combinators.NonEmpty (sepBy1)
import Control.Monad.Combinators (between)
import Data.Text (Text)

import Toml.Parser.Core (Parser, alphaNumChar, char, lexeme, text)
import Toml.Parser.String (basicStringP, literalStringP)
import Toml.Type.Key (Key (..), Piece (..))

import qualified Data.Text as Text


-- | Parser for bare key piece, like @foo@.
bareKeyPieceP :: Parser Text
bareKeyPieceP :: Parser Text
bareKeyPieceP = forall a. Parser a -> Parser a
lexeme forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String
bareStrP
  where
    bareStrP :: Parser String
    bareStrP :: Parser String
bareStrP = forall (f :: * -> *) a. Alternative f => f a -> f [a]
some forall a b. (a -> b) -> a -> b
$ forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
alphaNumChar forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
'_' forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
'-'

-- | Parser for 'Piece'.
keyComponentP :: Parser Piece
keyComponentP :: Parser Piece
keyComponentP = Text -> Piece
Piece forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    (Parser Text
bareKeyPieceP forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Text -> Text -> Text
quote Text
"\"" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
basicStringP) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Text -> Text -> Text
quote Text
"'" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
literalStringP))
  where
    -- adds " or ' to both sides
    quote :: Text -> Text -> Text
    quote :: Text -> Text -> Text
quote Text
q Text
t = Text
q forall a. Semigroup a => a -> a -> a
<> Text
t forall a. Semigroup a => a -> a -> a
<> Text
q

-- | Parser for 'Key': dot-separated list of 'Piece'.
keyP :: Parser Key
keyP :: Parser Key
keyP = NonEmpty Piece -> Key
Key forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Piece
keyComponentP forall (m :: * -> *) a sep.
Alternative m =>
m a -> m sep -> m (NonEmpty a)
`sepBy1` forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
'.'

-- | Parser for table name: 'Key' inside @[]@.
tableNameP :: Parser Key
tableNameP :: Parser Key
tableNameP = forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Text -> Parser Text
text Text
"[") (Text -> Parser Text
text Text
"]") Parser Key
keyP

-- | Parser for array of tables name: 'Key' inside @[[]]@.
tableArrayNameP :: Parser Key
tableArrayNameP :: Parser Key
tableArrayNameP = forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Text -> Parser Text
text Text
"[[") (Text -> Parser Text
text Text
"]]") Parser Key
keyP