{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoFieldSelectors #-}

{-|
Defines the types that make up a KDL document.

This module enables @-XNoFieldSelectors@, so none of the fields create implicit
selector functions. Instead, use @-XOverloadedRecordDot@,
@-XNamedFieldPuns@/@-XRecordWildCards@, or explicitly pattern-match.
-}
module KDL.Types (
  -- * Document
  Document,

  -- * NodeList
  NodeList (..),
  NodeListExtension (..),
  NodeListFormat (..),

  -- ** Helpers
  filterNodes,
  lookupNode,
  getArgAt,
  getArgsAt,
  getDashChildrenAt,
  getDashNodesAt,

  -- * Node
  Node (..),
  NodeExtension (..),
  NodeFormat (..),

  -- ** Helpers
  getArgs,
  getArg,
  getProps,
  getProp,

  -- * Entry
  Entry (..),
  EntryExtension (..),
  EntryFormat (..),

  -- * Value
  Value (..),
  ValueExtension (..),
  ValueFormat (..),
  ValueData (..),

  -- * Ann
  Ann (..),
  AnnExtension (..),
  AnnFormat (..),

  -- * Identifier
  Identifier (..),
  IdentifierExtension (..),
  IdentifierFormat (..),
  fromIdentifier,
  toIdentifier,

  -- * Span
  Span (..),

  -- * Re-exports
  def,
) where

import Control.Monad ((<=<))
import Data.Default (Default (..))
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Maybe (listToMaybe, mapMaybe)
import Data.Scientific (Scientific)
import Data.Text (Text)

{----- Document -----}

type Document = NodeList

{----- NodeList -----}

data NodeList = NodeList
  { NodeList -> [Node]
nodes :: [Node]
  , NodeList -> NodeListExtension
ext :: NodeListExtension
  }
  deriving (Int -> NodeList -> ShowS
[NodeList] -> ShowS
NodeList -> String
(Int -> NodeList -> ShowS)
-> (NodeList -> String) -> ([NodeList] -> ShowS) -> Show NodeList
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NodeList -> ShowS
showsPrec :: Int -> NodeList -> ShowS
$cshow :: NodeList -> String
show :: NodeList -> String
$cshowList :: [NodeList] -> ShowS
showList :: [NodeList] -> ShowS
Show, NodeList -> NodeList -> Bool
(NodeList -> NodeList -> Bool)
-> (NodeList -> NodeList -> Bool) -> Eq NodeList
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NodeList -> NodeList -> Bool
== :: NodeList -> NodeList -> Bool
$c/= :: NodeList -> NodeList -> Bool
/= :: NodeList -> NodeList -> Bool
Eq)

data NodeListExtension = NodeListExtension
  { NodeListExtension -> Maybe NodeListFormat
format :: Maybe NodeListFormat
  , NodeListExtension -> Span
span :: Span
  }
  deriving (Int -> NodeListExtension -> ShowS
[NodeListExtension] -> ShowS
NodeListExtension -> String
(Int -> NodeListExtension -> ShowS)
-> (NodeListExtension -> String)
-> ([NodeListExtension] -> ShowS)
-> Show NodeListExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NodeListExtension -> ShowS
showsPrec :: Int -> NodeListExtension -> ShowS
$cshow :: NodeListExtension -> String
show :: NodeListExtension -> String
$cshowList :: [NodeListExtension] -> ShowS
showList :: [NodeListExtension] -> ShowS
Show, NodeListExtension -> NodeListExtension -> Bool
(NodeListExtension -> NodeListExtension -> Bool)
-> (NodeListExtension -> NodeListExtension -> Bool)
-> Eq NodeListExtension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NodeListExtension -> NodeListExtension -> Bool
== :: NodeListExtension -> NodeListExtension -> Bool
$c/= :: NodeListExtension -> NodeListExtension -> Bool
/= :: NodeListExtension -> NodeListExtension -> Bool
Eq)

data NodeListFormat = NodeListFormat
  { NodeListFormat -> Text
leading :: Text
  -- ^ Whitespace and comments preceding the first node.
  , NodeListFormat -> Text
trailing :: Text
  -- ^ Whitespace and comments following the last node.
  }
  deriving (Int -> NodeListFormat -> ShowS
[NodeListFormat] -> ShowS
NodeListFormat -> String
(Int -> NodeListFormat -> ShowS)
-> (NodeListFormat -> String)
-> ([NodeListFormat] -> ShowS)
-> Show NodeListFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NodeListFormat -> ShowS
showsPrec :: Int -> NodeListFormat -> ShowS
$cshow :: NodeListFormat -> String
show :: NodeListFormat -> String
$cshowList :: [NodeListFormat] -> ShowS
showList :: [NodeListFormat] -> ShowS
Show, NodeListFormat -> NodeListFormat -> Bool
(NodeListFormat -> NodeListFormat -> Bool)
-> (NodeListFormat -> NodeListFormat -> Bool) -> Eq NodeListFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NodeListFormat -> NodeListFormat -> Bool
== :: NodeListFormat -> NodeListFormat -> Bool
$c/= :: NodeListFormat -> NodeListFormat -> Bool
/= :: NodeListFormat -> NodeListFormat -> Bool
Eq)

instance Default NodeListExtension where
  def :: NodeListExtension
def =
    NodeListExtension
      { format :: Maybe NodeListFormat
format = Maybe NodeListFormat
forall a. Default a => a
def
      , span :: Span
span = Span
forall a. Default a => a
def
      }
instance Default NodeListFormat where
  def :: NodeListFormat
def =
    NodeListFormat
      { leading :: Text
leading = Text
""
      , trailing :: Text
trailing = Text
""
      }

-- | A helper to get all nodes with the given name
filterNodes :: Text -> NodeList -> [Node]
filterNodes :: Text -> NodeList -> [Node]
filterNodes Text
name = (Node -> Bool) -> [Node] -> [Node]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
name) (Text -> Bool) -> (Node -> Text) -> Node -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.name.value)) ([Node] -> [Node]) -> (NodeList -> [Node]) -> NodeList -> [Node]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.nodes)

-- | A helper to get the first node with the given name
lookupNode :: Text -> NodeList -> Maybe Node
lookupNode :: Text -> NodeList -> Maybe Node
lookupNode Text
name = [Node] -> Maybe Node
forall a. [a] -> Maybe a
listToMaybe ([Node] -> Maybe Node)
-> (NodeList -> [Node]) -> NodeList -> Maybe Node
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NodeList -> [Node]
filterNodes Text
name

-- | A helper to get the first argument of the first node with the given name.
-- A utility for nodes that are acting like a key-value store.
--
-- == __Example__
--
-- @
-- let
--   config =
--     """
--     foo 1
--     """
-- Right doc <- pure $ parse config
-- getArgAt "foo" doc == Just (Number 1)
-- @
getArgAt :: Text -> NodeList -> Maybe Value
getArgAt :: Text -> NodeList -> Maybe Value
getArgAt Text
name = [Value] -> Maybe Value
forall a. [a] -> Maybe a
listToMaybe ([Value] -> Maybe Value)
-> (NodeList -> [Value]) -> NodeList -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NodeList -> [Value]
getArgsAt Text
name

-- | A helper to get all the arguments of the first node with the given name.
-- A utility for nodes that are acting like a key-value store with a list of values.
--
-- == __Example__
--
-- @
-- let
--   config =
--     """
--     foo 1 2 "test"
--     """
-- Right doc <- pure $ parse config
-- getArgsAt "foo" doc == [Number 1, Number 2, Text "test"]
-- @
getArgsAt :: Text -> NodeList -> [Value]
getArgsAt :: Text -> NodeList -> [Value]
getArgsAt Text
name = [Value] -> (Node -> [Value]) -> Maybe Node -> [Value]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Node -> [Value]
getArgs (Maybe Node -> [Value])
-> (NodeList -> Maybe Node) -> NodeList -> [Value]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NodeList -> Maybe Node
lookupNode Text
name

-- | A helper for getting child values following the KDL convention of being named "-".
--
-- == __Example__
--
-- @
-- let
--   config =
--     """
--     foo {
--       - 1
--       - 2
--       - "test"
--     }
--     """
-- Right doc <- pure $ parse config
-- getDashChildrenAt "foo" doc == [Number 1, Number 2, Text "test"]
-- @
getDashChildrenAt :: Text -> NodeList -> [Value]
getDashChildrenAt :: Text -> NodeList -> [Value]
getDashChildrenAt Text
name = (Node -> Maybe Value) -> [Node] -> [Value]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Node -> Maybe Value
getArg ([Node] -> [Value]) -> (NodeList -> [Node]) -> NodeList -> [Value]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NodeList -> [Node]
getDashNodesAt Text
name

-- | A helper for getting child nodes following the KDL convention of being named "-".
--
-- == __Example__
--
-- @
-- let
--   config =
--     """
--     foo {
--       - 1
--       - 2
--       - "test"
--     }
--     """
-- Right doc <- pure $ parse config
-- mapM getArg (getDashNodesAt "foo" doc) == Just [Number 1, Number 2, Text "test"]
-- @
getDashNodesAt :: Text -> NodeList -> [Node]
getDashNodesAt :: Text -> NodeList -> [Node]
getDashNodesAt Text
name = [Node] -> (NodeList -> [Node]) -> Maybe NodeList -> [Node]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Text -> NodeList -> [Node]
filterNodes Text
"-") (Maybe NodeList -> [Node])
-> (NodeList -> Maybe NodeList) -> NodeList -> [Node]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((.children) (Node -> Maybe NodeList)
-> (NodeList -> Maybe Node) -> NodeList -> Maybe NodeList
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Text -> NodeList -> Maybe Node
lookupNode Text
name)

{----- Ann -----}

data Ann = Ann
  { Ann -> Identifier
identifier :: Identifier
  , Ann -> AnnExtension
ext :: AnnExtension
  }
  deriving (Int -> Ann -> ShowS
[Ann] -> ShowS
Ann -> String
(Int -> Ann -> ShowS)
-> (Ann -> String) -> ([Ann] -> ShowS) -> Show Ann
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Ann -> ShowS
showsPrec :: Int -> Ann -> ShowS
$cshow :: Ann -> String
show :: Ann -> String
$cshowList :: [Ann] -> ShowS
showList :: [Ann] -> ShowS
Show, Ann -> Ann -> Bool
(Ann -> Ann -> Bool) -> (Ann -> Ann -> Bool) -> Eq Ann
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Ann -> Ann -> Bool
== :: Ann -> Ann -> Bool
$c/= :: Ann -> Ann -> Bool
/= :: Ann -> Ann -> Bool
Eq)

data AnnExtension = AnnExtension
  { AnnExtension -> Maybe AnnFormat
format :: Maybe AnnFormat
  , AnnExtension -> Span
span :: Span
  }
  deriving (Int -> AnnExtension -> ShowS
[AnnExtension] -> ShowS
AnnExtension -> String
(Int -> AnnExtension -> ShowS)
-> (AnnExtension -> String)
-> ([AnnExtension] -> ShowS)
-> Show AnnExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AnnExtension -> ShowS
showsPrec :: Int -> AnnExtension -> ShowS
$cshow :: AnnExtension -> String
show :: AnnExtension -> String
$cshowList :: [AnnExtension] -> ShowS
showList :: [AnnExtension] -> ShowS
Show, AnnExtension -> AnnExtension -> Bool
(AnnExtension -> AnnExtension -> Bool)
-> (AnnExtension -> AnnExtension -> Bool) -> Eq AnnExtension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AnnExtension -> AnnExtension -> Bool
== :: AnnExtension -> AnnExtension -> Bool
$c/= :: AnnExtension -> AnnExtension -> Bool
/= :: AnnExtension -> AnnExtension -> Bool
Eq)

data AnnFormat = AnnFormat
  { AnnFormat -> Text
leading :: Text
  -- ^ Whitespace and comments preceding the annotation itself.
  , AnnFormat -> Text
beforeId :: Text
  -- ^ Whitespace and comments between the opening `(` and the identifier.
  , AnnFormat -> Text
afterId :: Text
  -- ^ Whitespace and comments between the identifier and the closing `)`.
  , AnnFormat -> Text
trailing :: Text
  -- ^ Whitespace and comments following the annotation itself.
  }
  deriving (Int -> AnnFormat -> ShowS
[AnnFormat] -> ShowS
AnnFormat -> String
(Int -> AnnFormat -> ShowS)
-> (AnnFormat -> String)
-> ([AnnFormat] -> ShowS)
-> Show AnnFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AnnFormat -> ShowS
showsPrec :: Int -> AnnFormat -> ShowS
$cshow :: AnnFormat -> String
show :: AnnFormat -> String
$cshowList :: [AnnFormat] -> ShowS
showList :: [AnnFormat] -> ShowS
Show, AnnFormat -> AnnFormat -> Bool
(AnnFormat -> AnnFormat -> Bool)
-> (AnnFormat -> AnnFormat -> Bool) -> Eq AnnFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AnnFormat -> AnnFormat -> Bool
== :: AnnFormat -> AnnFormat -> Bool
$c/= :: AnnFormat -> AnnFormat -> Bool
/= :: AnnFormat -> AnnFormat -> Bool
Eq)

instance Default AnnExtension where
  def :: AnnExtension
def =
    AnnExtension
      { format :: Maybe AnnFormat
format = Maybe AnnFormat
forall a. Default a => a
def
      , span :: Span
span = Span
forall a. Default a => a
def
      }
instance Default AnnFormat where
  def :: AnnFormat
def =
    AnnFormat
      { leading :: Text
leading = Text
""
      , beforeId :: Text
beforeId = Text
""
      , afterId :: Text
afterId = Text
""
      , trailing :: Text
trailing = Text
""
      }

{----- Node -----}

data Node = Node
  { Node -> Maybe Ann
ann :: Maybe Ann
  , Node -> Identifier
name :: Identifier
  , Node -> [Entry]
entries :: [Entry]
  , Node -> Maybe NodeList
children :: Maybe NodeList
  , Node -> NodeExtension
ext :: NodeExtension
  }
  deriving (Int -> Node -> ShowS
[Node] -> ShowS
Node -> String
(Int -> Node -> ShowS)
-> (Node -> String) -> ([Node] -> ShowS) -> Show Node
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Node -> ShowS
showsPrec :: Int -> Node -> ShowS
$cshow :: Node -> String
show :: Node -> String
$cshowList :: [Node] -> ShowS
showList :: [Node] -> ShowS
Show, Node -> Node -> Bool
(Node -> Node -> Bool) -> (Node -> Node -> Bool) -> Eq Node
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Node -> Node -> Bool
== :: Node -> Node -> Bool
$c/= :: Node -> Node -> Bool
/= :: Node -> Node -> Bool
Eq)

data NodeExtension = NodeExtension
  { NodeExtension -> Maybe NodeFormat
format :: Maybe NodeFormat
  , NodeExtension -> Span
span :: Span
  }
  deriving (Int -> NodeExtension -> ShowS
[NodeExtension] -> ShowS
NodeExtension -> String
(Int -> NodeExtension -> ShowS)
-> (NodeExtension -> String)
-> ([NodeExtension] -> ShowS)
-> Show NodeExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NodeExtension -> ShowS
showsPrec :: Int -> NodeExtension -> ShowS
$cshow :: NodeExtension -> String
show :: NodeExtension -> String
$cshowList :: [NodeExtension] -> ShowS
showList :: [NodeExtension] -> ShowS
Show, NodeExtension -> NodeExtension -> Bool
(NodeExtension -> NodeExtension -> Bool)
-> (NodeExtension -> NodeExtension -> Bool) -> Eq NodeExtension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NodeExtension -> NodeExtension -> Bool
== :: NodeExtension -> NodeExtension -> Bool
$c/= :: NodeExtension -> NodeExtension -> Bool
/= :: NodeExtension -> NodeExtension -> Bool
Eq)

data NodeFormat = NodeFormat
  { NodeFormat -> Text
leading :: Text
  -- ^ Whitespace and comments preceding the node itself.
  , NodeFormat -> Text
beforeChildren :: Text
  -- ^ Whitespace and comments preceding the node's children block.
  , NodeFormat -> Text
beforeTerminator :: Text
  -- ^ Whitespace and comments right before the node's terminator.
  , NodeFormat -> Text
terminator :: Text
  -- ^ The terminator for the node.
  , NodeFormat -> Text
trailing :: Text
  -- ^ Whitespace and comments following the node, after the terminator.
  }
  deriving (Int -> NodeFormat -> ShowS
[NodeFormat] -> ShowS
NodeFormat -> String
(Int -> NodeFormat -> ShowS)
-> (NodeFormat -> String)
-> ([NodeFormat] -> ShowS)
-> Show NodeFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NodeFormat -> ShowS
showsPrec :: Int -> NodeFormat -> ShowS
$cshow :: NodeFormat -> String
show :: NodeFormat -> String
$cshowList :: [NodeFormat] -> ShowS
showList :: [NodeFormat] -> ShowS
Show, NodeFormat -> NodeFormat -> Bool
(NodeFormat -> NodeFormat -> Bool)
-> (NodeFormat -> NodeFormat -> Bool) -> Eq NodeFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NodeFormat -> NodeFormat -> Bool
== :: NodeFormat -> NodeFormat -> Bool
$c/= :: NodeFormat -> NodeFormat -> Bool
/= :: NodeFormat -> NodeFormat -> Bool
Eq)

instance Default NodeExtension where
  def :: NodeExtension
def =
    NodeExtension
      { format :: Maybe NodeFormat
format = Maybe NodeFormat
forall a. Default a => a
def
      , span :: Span
span = Span
forall a. Default a => a
def
      }
instance Default NodeFormat where
  def :: NodeFormat
def =
    NodeFormat
      { leading :: Text
leading = Text
""
      , beforeChildren :: Text
beforeChildren = Text
""
      , beforeTerminator :: Text
beforeTerminator = Text
""
      , terminator :: Text
terminator = Text
""
      , trailing :: Text
trailing = Text
""
      }

-- | Get all the positional arguments of the node.
getArgs :: Node -> [Value]
getArgs :: Node -> [Value]
getArgs Node
node =
  [ Value
value
  | Entry{name :: Entry -> Maybe Identifier
name = Maybe Identifier
Nothing, Value
value :: Value
value :: Entry -> Value
value} <- Node
node.entries
  ]

-- | Get the first argument of the node.
getArg :: Node -> Maybe Value
getArg :: Node -> Maybe Value
getArg = [Value] -> Maybe Value
forall a. [a] -> Maybe a
listToMaybe ([Value] -> Maybe Value)
-> (Node -> [Value]) -> Node -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Node -> [Value]
getArgs

-- | Get the properties of the node.
getProps :: Node -> Map Text Value
getProps :: Node -> Map Text Value
getProps Node
node =
  [(Text, Value)] -> Map Text Value
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
    [ (Identifier
name.value, Value
value)
    | Entry{name :: Entry -> Maybe Identifier
name = Just Identifier
name, Value
value :: Entry -> Value
value :: Value
value} <- Node
node.entries
    ]

-- | Get the property with the given name in the node.
getProp :: Text -> Node -> Maybe Value
getProp :: Text -> Node -> Maybe Value
getProp Text
name = Text -> Map Text Value -> Maybe Value
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
name (Map Text Value -> Maybe Value)
-> (Node -> Map Text Value) -> Node -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Node -> Map Text Value
getProps

{----- Entry -----}

data Entry = Entry
  { Entry -> Maybe Identifier
name :: Maybe Identifier
  -- ^ The name of the entry, if it's a property, Nothing if it's a positional arg
  , Entry -> Value
value :: Value
  , Entry -> EntryExtension
ext :: EntryExtension
  }
  deriving (Int -> Entry -> ShowS
[Entry] -> ShowS
Entry -> String
(Int -> Entry -> ShowS)
-> (Entry -> String) -> ([Entry] -> ShowS) -> Show Entry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Entry -> ShowS
showsPrec :: Int -> Entry -> ShowS
$cshow :: Entry -> String
show :: Entry -> String
$cshowList :: [Entry] -> ShowS
showList :: [Entry] -> ShowS
Show, Entry -> Entry -> Bool
(Entry -> Entry -> Bool) -> (Entry -> Entry -> Bool) -> Eq Entry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Entry -> Entry -> Bool
== :: Entry -> Entry -> Bool
$c/= :: Entry -> Entry -> Bool
/= :: Entry -> Entry -> Bool
Eq)

data EntryExtension = EntryExtension
  { EntryExtension -> Maybe EntryFormat
format :: Maybe EntryFormat
  , EntryExtension -> Span
span :: Span
  }
  deriving (Int -> EntryExtension -> ShowS
[EntryExtension] -> ShowS
EntryExtension -> String
(Int -> EntryExtension -> ShowS)
-> (EntryExtension -> String)
-> ([EntryExtension] -> ShowS)
-> Show EntryExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EntryExtension -> ShowS
showsPrec :: Int -> EntryExtension -> ShowS
$cshow :: EntryExtension -> String
show :: EntryExtension -> String
$cshowList :: [EntryExtension] -> ShowS
showList :: [EntryExtension] -> ShowS
Show, EntryExtension -> EntryExtension -> Bool
(EntryExtension -> EntryExtension -> Bool)
-> (EntryExtension -> EntryExtension -> Bool) -> Eq EntryExtension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EntryExtension -> EntryExtension -> Bool
== :: EntryExtension -> EntryExtension -> Bool
$c/= :: EntryExtension -> EntryExtension -> Bool
/= :: EntryExtension -> EntryExtension -> Bool
Eq)

data EntryFormat = EntryFormat
  { EntryFormat -> Text
leading :: Text
  -- ^ Whitespace and comments preceding the entry itself.
  , EntryFormat -> Text
afterKey :: Text
  -- ^ Whitespace and comments between an entry's key name and its equals sign.
  , EntryFormat -> Text
afterEq :: Text
  -- ^ Whitespace and comments between an entry's equals sign and its value.
  , EntryFormat -> Text
trailing :: Text
  -- ^ Whitespace and comments following the entry itself.
  }
  deriving (Int -> EntryFormat -> ShowS
[EntryFormat] -> ShowS
EntryFormat -> String
(Int -> EntryFormat -> ShowS)
-> (EntryFormat -> String)
-> ([EntryFormat] -> ShowS)
-> Show EntryFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EntryFormat -> ShowS
showsPrec :: Int -> EntryFormat -> ShowS
$cshow :: EntryFormat -> String
show :: EntryFormat -> String
$cshowList :: [EntryFormat] -> ShowS
showList :: [EntryFormat] -> ShowS
Show, EntryFormat -> EntryFormat -> Bool
(EntryFormat -> EntryFormat -> Bool)
-> (EntryFormat -> EntryFormat -> Bool) -> Eq EntryFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EntryFormat -> EntryFormat -> Bool
== :: EntryFormat -> EntryFormat -> Bool
$c/= :: EntryFormat -> EntryFormat -> Bool
/= :: EntryFormat -> EntryFormat -> Bool
Eq)

instance Default EntryExtension where
  def :: EntryExtension
def =
    EntryExtension
      { format :: Maybe EntryFormat
format = Maybe EntryFormat
forall a. Default a => a
def
      , span :: Span
span = Span
forall a. Default a => a
def
      }
instance Default EntryFormat where
  def :: EntryFormat
def =
    EntryFormat
      { leading :: Text
leading = Text
""
      , afterKey :: Text
afterKey = Text
""
      , afterEq :: Text
afterEq = Text
""
      , trailing :: Text
trailing = Text
""
      }

{----- Value -----}

data Value = Value
  { Value -> Maybe Ann
ann :: Maybe Ann
  , Value -> ValueData
data_ :: ValueData
  , Value -> ValueExtension
ext :: ValueExtension
  }
  deriving (Int -> Value -> ShowS
[Value] -> ShowS
Value -> String
(Int -> Value -> ShowS)
-> (Value -> String) -> ([Value] -> ShowS) -> Show Value
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Value -> ShowS
showsPrec :: Int -> Value -> ShowS
$cshow :: Value -> String
show :: Value -> String
$cshowList :: [Value] -> ShowS
showList :: [Value] -> ShowS
Show, Value -> Value -> Bool
(Value -> Value -> Bool) -> (Value -> Value -> Bool) -> Eq Value
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Value -> Value -> Bool
== :: Value -> Value -> Bool
$c/= :: Value -> Value -> Bool
/= :: Value -> Value -> Bool
Eq)

data ValueExtension = ValueExtension
  { ValueExtension -> Maybe ValueFormat
format :: Maybe ValueFormat
  , ValueExtension -> Span
span :: Span
  }
  deriving (Int -> ValueExtension -> ShowS
[ValueExtension] -> ShowS
ValueExtension -> String
(Int -> ValueExtension -> ShowS)
-> (ValueExtension -> String)
-> ([ValueExtension] -> ShowS)
-> Show ValueExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ValueExtension -> ShowS
showsPrec :: Int -> ValueExtension -> ShowS
$cshow :: ValueExtension -> String
show :: ValueExtension -> String
$cshowList :: [ValueExtension] -> ShowS
showList :: [ValueExtension] -> ShowS
Show, ValueExtension -> ValueExtension -> Bool
(ValueExtension -> ValueExtension -> Bool)
-> (ValueExtension -> ValueExtension -> Bool) -> Eq ValueExtension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ValueExtension -> ValueExtension -> Bool
== :: ValueExtension -> ValueExtension -> Bool
$c/= :: ValueExtension -> ValueExtension -> Bool
/= :: ValueExtension -> ValueExtension -> Bool
Eq)

data ValueFormat = ValueFormat
  { ValueFormat -> Maybe Text
repr :: Maybe Text
  -- ^ The actual text representation of the value.
  }
  deriving (Int -> ValueFormat -> ShowS
[ValueFormat] -> ShowS
ValueFormat -> String
(Int -> ValueFormat -> ShowS)
-> (ValueFormat -> String)
-> ([ValueFormat] -> ShowS)
-> Show ValueFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ValueFormat -> ShowS
showsPrec :: Int -> ValueFormat -> ShowS
$cshow :: ValueFormat -> String
show :: ValueFormat -> String
$cshowList :: [ValueFormat] -> ShowS
showList :: [ValueFormat] -> ShowS
Show, ValueFormat -> ValueFormat -> Bool
(ValueFormat -> ValueFormat -> Bool)
-> (ValueFormat -> ValueFormat -> Bool) -> Eq ValueFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ValueFormat -> ValueFormat -> Bool
== :: ValueFormat -> ValueFormat -> Bool
$c/= :: ValueFormat -> ValueFormat -> Bool
/= :: ValueFormat -> ValueFormat -> Bool
Eq)

instance Default ValueExtension where
  def :: ValueExtension
def =
    ValueExtension
      { format :: Maybe ValueFormat
format = Maybe ValueFormat
forall a. Default a => a
def
      , span :: Span
span = Span
forall a. Default a => a
def
      }
instance Default ValueFormat where
  def :: ValueFormat
def =
    ValueFormat
      { repr :: Maybe Text
repr = Maybe Text
forall a. Maybe a
Nothing
      }

data ValueData
  = String Text
  | Number Scientific
  | Bool Bool
  | Inf
  | NegInf
  | NaN
  | Null
  deriving (Int -> ValueData -> ShowS
[ValueData] -> ShowS
ValueData -> String
(Int -> ValueData -> ShowS)
-> (ValueData -> String)
-> ([ValueData] -> ShowS)
-> Show ValueData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ValueData -> ShowS
showsPrec :: Int -> ValueData -> ShowS
$cshow :: ValueData -> String
show :: ValueData -> String
$cshowList :: [ValueData] -> ShowS
showList :: [ValueData] -> ShowS
Show, ValueData -> ValueData -> Bool
(ValueData -> ValueData -> Bool)
-> (ValueData -> ValueData -> Bool) -> Eq ValueData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ValueData -> ValueData -> Bool
== :: ValueData -> ValueData -> Bool
$c/= :: ValueData -> ValueData -> Bool
/= :: ValueData -> ValueData -> Bool
Eq)

{----- Identifier -----}

data Identifier = Identifier
  { Identifier -> Text
value :: Text
  , Identifier -> IdentifierExtension
ext :: IdentifierExtension
  }
  deriving (Int -> Identifier -> ShowS
[Identifier] -> ShowS
Identifier -> String
(Int -> Identifier -> ShowS)
-> (Identifier -> String)
-> ([Identifier] -> ShowS)
-> Show Identifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Identifier -> ShowS
showsPrec :: Int -> Identifier -> ShowS
$cshow :: Identifier -> String
show :: Identifier -> String
$cshowList :: [Identifier] -> ShowS
showList :: [Identifier] -> ShowS
Show, Identifier -> Identifier -> Bool
(Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool) -> Eq Identifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Identifier -> Identifier -> Bool
== :: Identifier -> Identifier -> Bool
$c/= :: Identifier -> Identifier -> Bool
/= :: Identifier -> Identifier -> Bool
Eq, Eq Identifier
Eq Identifier =>
(Identifier -> Identifier -> Ordering)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Identifier)
-> (Identifier -> Identifier -> Identifier)
-> Ord Identifier
Identifier -> Identifier -> Bool
Identifier -> Identifier -> Ordering
Identifier -> Identifier -> Identifier
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Identifier -> Identifier -> Ordering
compare :: Identifier -> Identifier -> Ordering
$c< :: Identifier -> Identifier -> Bool
< :: Identifier -> Identifier -> Bool
$c<= :: Identifier -> Identifier -> Bool
<= :: Identifier -> Identifier -> Bool
$c> :: Identifier -> Identifier -> Bool
> :: Identifier -> Identifier -> Bool
$c>= :: Identifier -> Identifier -> Bool
>= :: Identifier -> Identifier -> Bool
$cmax :: Identifier -> Identifier -> Identifier
max :: Identifier -> Identifier -> Identifier
$cmin :: Identifier -> Identifier -> Identifier
min :: Identifier -> Identifier -> Identifier
Ord)

data IdentifierExtension = IdentifierExtension
  { IdentifierExtension -> Maybe IdentifierFormat
format :: Maybe IdentifierFormat
  , IdentifierExtension -> Span
span :: Span
  }
  deriving (Int -> IdentifierExtension -> ShowS
[IdentifierExtension] -> ShowS
IdentifierExtension -> String
(Int -> IdentifierExtension -> ShowS)
-> (IdentifierExtension -> String)
-> ([IdentifierExtension] -> ShowS)
-> Show IdentifierExtension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IdentifierExtension -> ShowS
showsPrec :: Int -> IdentifierExtension -> ShowS
$cshow :: IdentifierExtension -> String
show :: IdentifierExtension -> String
$cshowList :: [IdentifierExtension] -> ShowS
showList :: [IdentifierExtension] -> ShowS
Show, IdentifierExtension -> IdentifierExtension -> Bool
(IdentifierExtension -> IdentifierExtension -> Bool)
-> (IdentifierExtension -> IdentifierExtension -> Bool)
-> Eq IdentifierExtension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IdentifierExtension -> IdentifierExtension -> Bool
== :: IdentifierExtension -> IdentifierExtension -> Bool
$c/= :: IdentifierExtension -> IdentifierExtension -> Bool
/= :: IdentifierExtension -> IdentifierExtension -> Bool
Eq, Eq IdentifierExtension
Eq IdentifierExtension =>
(IdentifierExtension -> IdentifierExtension -> Ordering)
-> (IdentifierExtension -> IdentifierExtension -> Bool)
-> (IdentifierExtension -> IdentifierExtension -> Bool)
-> (IdentifierExtension -> IdentifierExtension -> Bool)
-> (IdentifierExtension -> IdentifierExtension -> Bool)
-> (IdentifierExtension
    -> IdentifierExtension -> IdentifierExtension)
-> (IdentifierExtension
    -> IdentifierExtension -> IdentifierExtension)
-> Ord IdentifierExtension
IdentifierExtension -> IdentifierExtension -> Bool
IdentifierExtension -> IdentifierExtension -> Ordering
IdentifierExtension -> IdentifierExtension -> IdentifierExtension
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IdentifierExtension -> IdentifierExtension -> Ordering
compare :: IdentifierExtension -> IdentifierExtension -> Ordering
$c< :: IdentifierExtension -> IdentifierExtension -> Bool
< :: IdentifierExtension -> IdentifierExtension -> Bool
$c<= :: IdentifierExtension -> IdentifierExtension -> Bool
<= :: IdentifierExtension -> IdentifierExtension -> Bool
$c> :: IdentifierExtension -> IdentifierExtension -> Bool
> :: IdentifierExtension -> IdentifierExtension -> Bool
$c>= :: IdentifierExtension -> IdentifierExtension -> Bool
>= :: IdentifierExtension -> IdentifierExtension -> Bool
$cmax :: IdentifierExtension -> IdentifierExtension -> IdentifierExtension
max :: IdentifierExtension -> IdentifierExtension -> IdentifierExtension
$cmin :: IdentifierExtension -> IdentifierExtension -> IdentifierExtension
min :: IdentifierExtension -> IdentifierExtension -> IdentifierExtension
Ord)

data IdentifierFormat = IdentifierFormat
  { IdentifierFormat -> Maybe Text
repr :: Maybe Text
  }
  deriving (Int -> IdentifierFormat -> ShowS
[IdentifierFormat] -> ShowS
IdentifierFormat -> String
(Int -> IdentifierFormat -> ShowS)
-> (IdentifierFormat -> String)
-> ([IdentifierFormat] -> ShowS)
-> Show IdentifierFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IdentifierFormat -> ShowS
showsPrec :: Int -> IdentifierFormat -> ShowS
$cshow :: IdentifierFormat -> String
show :: IdentifierFormat -> String
$cshowList :: [IdentifierFormat] -> ShowS
showList :: [IdentifierFormat] -> ShowS
Show, IdentifierFormat -> IdentifierFormat -> Bool
(IdentifierFormat -> IdentifierFormat -> Bool)
-> (IdentifierFormat -> IdentifierFormat -> Bool)
-> Eq IdentifierFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IdentifierFormat -> IdentifierFormat -> Bool
== :: IdentifierFormat -> IdentifierFormat -> Bool
$c/= :: IdentifierFormat -> IdentifierFormat -> Bool
/= :: IdentifierFormat -> IdentifierFormat -> Bool
Eq, Eq IdentifierFormat
Eq IdentifierFormat =>
(IdentifierFormat -> IdentifierFormat -> Ordering)
-> (IdentifierFormat -> IdentifierFormat -> Bool)
-> (IdentifierFormat -> IdentifierFormat -> Bool)
-> (IdentifierFormat -> IdentifierFormat -> Bool)
-> (IdentifierFormat -> IdentifierFormat -> Bool)
-> (IdentifierFormat -> IdentifierFormat -> IdentifierFormat)
-> (IdentifierFormat -> IdentifierFormat -> IdentifierFormat)
-> Ord IdentifierFormat
IdentifierFormat -> IdentifierFormat -> Bool
IdentifierFormat -> IdentifierFormat -> Ordering
IdentifierFormat -> IdentifierFormat -> IdentifierFormat
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IdentifierFormat -> IdentifierFormat -> Ordering
compare :: IdentifierFormat -> IdentifierFormat -> Ordering
$c< :: IdentifierFormat -> IdentifierFormat -> Bool
< :: IdentifierFormat -> IdentifierFormat -> Bool
$c<= :: IdentifierFormat -> IdentifierFormat -> Bool
<= :: IdentifierFormat -> IdentifierFormat -> Bool
$c> :: IdentifierFormat -> IdentifierFormat -> Bool
> :: IdentifierFormat -> IdentifierFormat -> Bool
$c>= :: IdentifierFormat -> IdentifierFormat -> Bool
>= :: IdentifierFormat -> IdentifierFormat -> Bool
$cmax :: IdentifierFormat -> IdentifierFormat -> IdentifierFormat
max :: IdentifierFormat -> IdentifierFormat -> IdentifierFormat
$cmin :: IdentifierFormat -> IdentifierFormat -> IdentifierFormat
min :: IdentifierFormat -> IdentifierFormat -> IdentifierFormat
Ord)

instance Default IdentifierExtension where
  def :: IdentifierExtension
def =
    IdentifierExtension
      { format :: Maybe IdentifierFormat
format = Maybe IdentifierFormat
forall a. Default a => a
def
      , span :: Span
span = Span
forall a. Default a => a
def
      }
instance Default IdentifierFormat where
  def :: IdentifierFormat
def =
    IdentifierFormat
      { repr :: Maybe Text
repr = Maybe Text
forall a. Maybe a
Nothing
      }

fromIdentifier :: Identifier -> Text
fromIdentifier :: Identifier -> Text
fromIdentifier = (.value)

toIdentifier :: Text -> Identifier
toIdentifier :: Text -> Identifier
toIdentifier Text
value = Identifier{value :: Text
value = Text
value, ext :: IdentifierExtension
ext = IdentifierExtension
forall a. Default a => a
def}

{----- Span -----}

-- | The span of a KDL element, if parsed with 'includeSpans'. If 'includeSpans'
-- was not enabled, all fields are set to 0.
data Span = Span
  { Span -> Int
startLine :: Int
  , Span -> Int
startCol :: Int
  , Span -> Int
endLine :: Int
  , Span -> Int
endCol :: Int
  }
  deriving (Int -> Span -> ShowS
[Span] -> ShowS
Span -> String
(Int -> Span -> ShowS)
-> (Span -> String) -> ([Span] -> ShowS) -> Show Span
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Span -> ShowS
showsPrec :: Int -> Span -> ShowS
$cshow :: Span -> String
show :: Span -> String
$cshowList :: [Span] -> ShowS
showList :: [Span] -> ShowS
Show, Span -> Span -> Bool
(Span -> Span -> Bool) -> (Span -> Span -> Bool) -> Eq Span
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Span -> Span -> Bool
== :: Span -> Span -> Bool
$c/= :: Span -> Span -> Bool
/= :: Span -> Span -> Bool
Eq, Eq Span
Eq Span =>
(Span -> Span -> Ordering)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Bool)
-> (Span -> Span -> Span)
-> (Span -> Span -> Span)
-> Ord Span
Span -> Span -> Bool
Span -> Span -> Ordering
Span -> Span -> Span
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Span -> Span -> Ordering
compare :: Span -> Span -> Ordering
$c< :: Span -> Span -> Bool
< :: Span -> Span -> Bool
$c<= :: Span -> Span -> Bool
<= :: Span -> Span -> Bool
$c> :: Span -> Span -> Bool
> :: Span -> Span -> Bool
$c>= :: Span -> Span -> Bool
>= :: Span -> Span -> Bool
$cmax :: Span -> Span -> Span
max :: Span -> Span -> Span
$cmin :: Span -> Span -> Span
min :: Span -> Span -> Span
Ord)

instance Default Span where
  def :: Span
def =
    Span
      { startLine :: Int
startLine = Int
0
      , startCol :: Int
startCol = Int
0
      , endLine :: Int
endLine = Int
0
      , endCol :: Int
endCol = Int
0
      }