{-# LANGUAGE PatternSynonyms #-}
{-# OPTIONS_HADDOCK not-home #-}

-- | The types of the syntax tree.
--
-- This module is intended for internal use only, and may change without warning
-- in subsequent releases.
module Yamlet.Internal.Syntax
  ( -- * Documents
    Document (..)
  , YamlVersion (..)
  , document

    -- * Nodes
  , Node (..)
  , Content (.., ScalarContent)
  , Props (..)
  , noProps
  , Tag (..)
  , ScalarStyle (..)
  , isBlockScalar
  , CollectionStyle (..)

    -- ** Construction
  , contentNode
  , scalarNode
  , plainNode
  , sequenceNode
  , mappingNode

    -- * Comments
  , Comments (..)
  , noComments
  , withComments
  , Commented (..)
  , Line (.., Comment)

    -- * Positions
  , Offset (..)
  , noOffset
  , Located (..)

    -- * Copies
  , copyDocument
  , copyNode
  , copyComments
  ) where

import Control.DeepSeq
import Data.Text qualified as T
import GHC.Generics

import Yamlet.Internal.Utils

-- | A document of a YAML stream.
data Document = Document
  { Document -> Maybe YamlVersion
version :: !(Maybe YamlVersion)
  -- ^ The version from the @%YAML@ directive.
  , Document -> Bool
explicitStart :: !Bool
  -- ^ The document starts with a @---@ marker.
  , Document -> Bool
explicitEnd :: !Bool
  -- ^ The document ends with a @...@ marker.
  , Document -> Comments
docComments :: !Comments
  -- ^ The lines before the directives or the @---@ marker, the comment on the
  -- line of the marker and the lines at the end of the document: below the
  -- @...@ marker, or below a flow collection root.
  , Document -> Node
root :: !Node
  }
  deriving stock (Document -> Document -> Bool
(Document -> Document -> Bool)
-> (Document -> Document -> Bool) -> Eq Document
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Document -> Document -> Bool
== :: Document -> Document -> Bool
$c/= :: Document -> Document -> Bool
/= :: Document -> Document -> Bool
Eq, Int -> Document -> ShowS
[Document] -> ShowS
Document -> String
(Int -> Document -> ShowS)
-> (Document -> String) -> ([Document] -> ShowS) -> Show Document
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Document -> ShowS
showsPrec :: Int -> Document -> ShowS
$cshow :: Document -> String
show :: Document -> String
$cshowList :: [Document] -> ShowS
showList :: [Document] -> ShowS
Show, (forall x. Document -> Rep Document x)
-> (forall x. Rep Document x -> Document) -> Generic Document
forall x. Rep Document x -> Document
forall x. Document -> Rep Document x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Document -> Rep Document x
from :: forall x. Document -> Rep Document x
$cto :: forall x. Rep Document x -> Document
to :: forall x. Rep Document x -> Document
Generic)
  deriving anyclass (Document -> ()
(Document -> ()) -> NFData Document
forall a. (a -> ()) -> NFData a
$crnf :: Document -> ()
rnf :: Document -> ()
NFData)

-- | The version of YAML that a document declares.
data YamlVersion = YamlVersion
  { YamlVersion -> Int
major :: !Int
  , YamlVersion -> Int
minor :: !Int
  }
  deriving stock (YamlVersion -> YamlVersion -> Bool
(YamlVersion -> YamlVersion -> Bool)
-> (YamlVersion -> YamlVersion -> Bool) -> Eq YamlVersion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: YamlVersion -> YamlVersion -> Bool
== :: YamlVersion -> YamlVersion -> Bool
$c/= :: YamlVersion -> YamlVersion -> Bool
/= :: YamlVersion -> YamlVersion -> Bool
Eq, Eq YamlVersion
Eq YamlVersion =>
(YamlVersion -> YamlVersion -> Ordering)
-> (YamlVersion -> YamlVersion -> Bool)
-> (YamlVersion -> YamlVersion -> Bool)
-> (YamlVersion -> YamlVersion -> Bool)
-> (YamlVersion -> YamlVersion -> Bool)
-> (YamlVersion -> YamlVersion -> YamlVersion)
-> (YamlVersion -> YamlVersion -> YamlVersion)
-> Ord YamlVersion
YamlVersion -> YamlVersion -> Bool
YamlVersion -> YamlVersion -> Ordering
YamlVersion -> YamlVersion -> YamlVersion
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 :: YamlVersion -> YamlVersion -> Ordering
compare :: YamlVersion -> YamlVersion -> Ordering
$c< :: YamlVersion -> YamlVersion -> Bool
< :: YamlVersion -> YamlVersion -> Bool
$c<= :: YamlVersion -> YamlVersion -> Bool
<= :: YamlVersion -> YamlVersion -> Bool
$c> :: YamlVersion -> YamlVersion -> Bool
> :: YamlVersion -> YamlVersion -> Bool
$c>= :: YamlVersion -> YamlVersion -> Bool
>= :: YamlVersion -> YamlVersion -> Bool
$cmax :: YamlVersion -> YamlVersion -> YamlVersion
max :: YamlVersion -> YamlVersion -> YamlVersion
$cmin :: YamlVersion -> YamlVersion -> YamlVersion
min :: YamlVersion -> YamlVersion -> YamlVersion
Ord, Int -> YamlVersion -> ShowS
[YamlVersion] -> ShowS
YamlVersion -> String
(Int -> YamlVersion -> ShowS)
-> (YamlVersion -> String)
-> ([YamlVersion] -> ShowS)
-> Show YamlVersion
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> YamlVersion -> ShowS
showsPrec :: Int -> YamlVersion -> ShowS
$cshow :: YamlVersion -> String
show :: YamlVersion -> String
$cshowList :: [YamlVersion] -> ShowS
showList :: [YamlVersion] -> ShowS
Show, (forall x. YamlVersion -> Rep YamlVersion x)
-> (forall x. Rep YamlVersion x -> YamlVersion)
-> Generic YamlVersion
forall x. Rep YamlVersion x -> YamlVersion
forall x. YamlVersion -> Rep YamlVersion x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. YamlVersion -> Rep YamlVersion x
from :: forall x. YamlVersion -> Rep YamlVersion x
$cto :: forall x. Rep YamlVersion x -> YamlVersion
to :: forall x. Rep YamlVersion x -> YamlVersion
Generic)
  deriving anyclass (YamlVersion -> ()
(YamlVersion -> ()) -> NFData YamlVersion
forall a. (a -> ()) -> NFData a
$crnf :: YamlVersion -> ()
rnf :: YamlVersion -> ()
NFData)

-- | A document with the given root, without directives, markers and comments.
document :: Node -> Document
document :: Node -> Document
document Node
n =
  Document
    { version :: Maybe YamlVersion
version = Maybe YamlVersion
forall a. Maybe a
Nothing
    , explicitStart :: Bool
explicitStart = Bool
False
    , explicitEnd :: Bool
explicitEnd = Bool
False
    , docComments :: Comments
docComments = Comments
noComments
    , root :: Node
root = Node
n
    }

-- | A node of a document.
data Node = Node
  { Node -> Offset
offset :: !Offset
  -- ^ The position of the first character of the content.
  , Node -> Offset
endOffset :: !Offset
  -- ^ The position after the last character of the content.
  , Node -> Props
props :: !Props
  , Node -> Comments
comments :: !Comments
  , Node -> Content
content :: !Content
  }
  deriving stock (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, 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, (forall x. Node -> Rep Node x)
-> (forall x. Rep Node x -> Node) -> Generic Node
forall x. Rep Node x -> Node
forall x. Node -> Rep Node x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Node -> Rep Node x
from :: forall x. Node -> Rep Node x
$cto :: forall x. Rep Node x -> Node
to :: forall x. Rep Node x -> Node
Generic)
  deriving anyclass (Node -> ()
(Node -> ()) -> NFData Node
forall a. (a -> ()) -> NFData a
$crnf :: Node -> ()
rnf :: Node -> ()
NFData)

-- | The content of a node.
data Content
  = -- | A scalar with the positions in its text where the source continues on
    -- a new line. A position counts the characters from the start of the
    -- text, and the positions are in ascending order. The parser gives them
    -- for the plain, quoted and folded styles, which join the lines of the
    -- source, so that the renderer can write the text on the same lines. The
    -- renderer ignores a position where the style of the output cannot start
    -- a new line and keep the text.
    ScalarLinesContent !ScalarStyle !T.Text ![Int]
  | SequenceContent !CollectionStyle ![Node]
  | MappingContent !CollectionStyle ![(Node, Node)]
  | -- | An alias, with the name of its anchor. An alias has no properties.
    AliasContent !T.Text
  deriving stock (Content -> Content -> Bool
(Content -> Content -> Bool)
-> (Content -> Content -> Bool) -> Eq Content
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Content -> Content -> Bool
== :: Content -> Content -> Bool
$c/= :: Content -> Content -> Bool
/= :: Content -> Content -> Bool
Eq, Int -> Content -> ShowS
[Content] -> ShowS
Content -> String
(Int -> Content -> ShowS)
-> (Content -> String) -> ([Content] -> ShowS) -> Show Content
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Content -> ShowS
showsPrec :: Int -> Content -> ShowS
$cshow :: Content -> String
show :: Content -> String
$cshowList :: [Content] -> ShowS
showList :: [Content] -> ShowS
Show, (forall x. Content -> Rep Content x)
-> (forall x. Rep Content x -> Content) -> Generic Content
forall x. Rep Content x -> Content
forall x. Content -> Rep Content x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Content -> Rep Content x
from :: forall x. Content -> Rep Content x
$cto :: forall x. Rep Content x -> Content
to :: forall x. Rep Content x -> Content
Generic)

-- | A scalar without positions of new lines. As a pattern, it matches every
-- scalar and ignores its positions.
pattern ScalarContent :: ScalarStyle -> T.Text -> Content
pattern $bScalarContent :: ScalarStyle -> Text -> Content
$mScalarContent :: forall {r}.
Content -> (ScalarStyle -> Text -> r) -> ((# #) -> r) -> r
ScalarContent style t <- ScalarLinesContent style t _
  where
    ScalarContent ScalarStyle
style Text
t = ScalarStyle -> Text -> [Int] -> Content
ScalarLinesContent ScalarStyle
style Text
t []

{-# COMPLETE ScalarContent, SequenceContent, MappingContent, AliasContent #-}

-- The instances of the sum types are written by hand, because GHC does not
-- always remove the generic representation of a sum type. A strict field of
-- a type without lazy parts, e.g. a text, is already in normal form.
instance NFData Content where
  rnf :: Content -> ()
rnf = \case
    ScalarLinesContent ScalarStyle
_ Text
_ [Int]
ls -> [Int] -> ()
forall a. NFData a => a -> ()
rnf [Int]
ls
    SequenceContent CollectionStyle
_ [Node]
xs -> [Node] -> ()
forall a. NFData a => a -> ()
rnf [Node]
xs
    MappingContent CollectionStyle
_ [(Node, Node)]
kvs -> [(Node, Node)] -> ()
forall a. NFData a => a -> ()
rnf [(Node, Node)]
kvs
    AliasContent Text
_ -> ()

-- | The properties of a node.
data Props = Props
  { Props -> Maybe Text
anchor :: !(Maybe T.Text)
  , Props -> Tag
tag :: !Tag
  }
  deriving stock (Props -> Props -> Bool
(Props -> Props -> Bool) -> (Props -> Props -> Bool) -> Eq Props
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Props -> Props -> Bool
== :: Props -> Props -> Bool
$c/= :: Props -> Props -> Bool
/= :: Props -> Props -> Bool
Eq, Int -> Props -> ShowS
[Props] -> ShowS
Props -> String
(Int -> Props -> ShowS)
-> (Props -> String) -> ([Props] -> ShowS) -> Show Props
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Props -> ShowS
showsPrec :: Int -> Props -> ShowS
$cshow :: Props -> String
show :: Props -> String
$cshowList :: [Props] -> ShowS
showList :: [Props] -> ShowS
Show, (forall x. Props -> Rep Props x)
-> (forall x. Rep Props x -> Props) -> Generic Props
forall x. Rep Props x -> Props
forall x. Props -> Rep Props x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Props -> Rep Props x
from :: forall x. Props -> Rep Props x
$cto :: forall x. Rep Props x -> Props
to :: forall x. Rep Props x -> Props
Generic)
  deriving anyclass (Props -> ()
(Props -> ()) -> NFData Props
forall a. (a -> ()) -> NFData a
$crnf :: Props -> ()
rnf :: Props -> ()
NFData)

-- | No anchor and no tag.
noProps :: Props
noProps :: Props
noProps = Maybe Text -> Tag -> Props
Props Maybe Text
forall a. Maybe a
Nothing Tag
NoTag

-- | The tag of a node after the tag handles are expanded.
data Tag
  = -- | The node has no tag.
    NoTag
  | -- | The @!@ tag.
    NonSpecificTag
  | -- | A specific tag, e.g. @tag:yaml.org,2002:str@ for @!!str@. YAML has
    -- no syntax for the empty tag or a tag of one character, e.g. @x@ or
    -- @!@. The renderer writes such a tag as @!@, which reads back as
    -- 'NonSpecificTag'.
    Tag !T.Text
  deriving stock (Tag -> Tag -> Bool
(Tag -> Tag -> Bool) -> (Tag -> Tag -> Bool) -> Eq Tag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Tag -> Tag -> Bool
== :: Tag -> Tag -> Bool
$c/= :: Tag -> Tag -> Bool
/= :: Tag -> Tag -> Bool
Eq, Eq Tag
Eq Tag =>
(Tag -> Tag -> Ordering)
-> (Tag -> Tag -> Bool)
-> (Tag -> Tag -> Bool)
-> (Tag -> Tag -> Bool)
-> (Tag -> Tag -> Bool)
-> (Tag -> Tag -> Tag)
-> (Tag -> Tag -> Tag)
-> Ord Tag
Tag -> Tag -> Bool
Tag -> Tag -> Ordering
Tag -> Tag -> Tag
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 :: Tag -> Tag -> Ordering
compare :: Tag -> Tag -> Ordering
$c< :: Tag -> Tag -> Bool
< :: Tag -> Tag -> Bool
$c<= :: Tag -> Tag -> Bool
<= :: Tag -> Tag -> Bool
$c> :: Tag -> Tag -> Bool
> :: Tag -> Tag -> Bool
$c>= :: Tag -> Tag -> Bool
>= :: Tag -> Tag -> Bool
$cmax :: Tag -> Tag -> Tag
max :: Tag -> Tag -> Tag
$cmin :: Tag -> Tag -> Tag
min :: Tag -> Tag -> Tag
Ord, Int -> Tag -> ShowS
[Tag] -> ShowS
Tag -> String
(Int -> Tag -> ShowS)
-> (Tag -> String) -> ([Tag] -> ShowS) -> Show Tag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Tag -> ShowS
showsPrec :: Int -> Tag -> ShowS
$cshow :: Tag -> String
show :: Tag -> String
$cshowList :: [Tag] -> ShowS
showList :: [Tag] -> ShowS
Show, (forall x. Tag -> Rep Tag x)
-> (forall x. Rep Tag x -> Tag) -> Generic Tag
forall x. Rep Tag x -> Tag
forall x. Tag -> Rep Tag x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Tag -> Rep Tag x
from :: forall x. Tag -> Rep Tag x
$cto :: forall x. Rep Tag x -> Tag
to :: forall x. Rep Tag x -> Tag
Generic)

instance NFData Tag where
  rnf :: Tag -> ()
rnf = Tag -> ()
forall a. a -> ()
rwhnf

-- | The style of a scalar: without quotes, in single or double quotes, or a
-- literal (@|@) or folded (@>@) block scalar.
data ScalarStyle
  = Plain
  | SingleQuoted
  | DoubleQuoted
  | Literal
  | Folded
  deriving stock (ScalarStyle -> ScalarStyle -> Bool
(ScalarStyle -> ScalarStyle -> Bool)
-> (ScalarStyle -> ScalarStyle -> Bool) -> Eq ScalarStyle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ScalarStyle -> ScalarStyle -> Bool
== :: ScalarStyle -> ScalarStyle -> Bool
$c/= :: ScalarStyle -> ScalarStyle -> Bool
/= :: ScalarStyle -> ScalarStyle -> Bool
Eq, Eq ScalarStyle
Eq ScalarStyle =>
(ScalarStyle -> ScalarStyle -> Ordering)
-> (ScalarStyle -> ScalarStyle -> Bool)
-> (ScalarStyle -> ScalarStyle -> Bool)
-> (ScalarStyle -> ScalarStyle -> Bool)
-> (ScalarStyle -> ScalarStyle -> Bool)
-> (ScalarStyle -> ScalarStyle -> ScalarStyle)
-> (ScalarStyle -> ScalarStyle -> ScalarStyle)
-> Ord ScalarStyle
ScalarStyle -> ScalarStyle -> Bool
ScalarStyle -> ScalarStyle -> Ordering
ScalarStyle -> ScalarStyle -> ScalarStyle
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 :: ScalarStyle -> ScalarStyle -> Ordering
compare :: ScalarStyle -> ScalarStyle -> Ordering
$c< :: ScalarStyle -> ScalarStyle -> Bool
< :: ScalarStyle -> ScalarStyle -> Bool
$c<= :: ScalarStyle -> ScalarStyle -> Bool
<= :: ScalarStyle -> ScalarStyle -> Bool
$c> :: ScalarStyle -> ScalarStyle -> Bool
> :: ScalarStyle -> ScalarStyle -> Bool
$c>= :: ScalarStyle -> ScalarStyle -> Bool
>= :: ScalarStyle -> ScalarStyle -> Bool
$cmax :: ScalarStyle -> ScalarStyle -> ScalarStyle
max :: ScalarStyle -> ScalarStyle -> ScalarStyle
$cmin :: ScalarStyle -> ScalarStyle -> ScalarStyle
min :: ScalarStyle -> ScalarStyle -> ScalarStyle
Ord, Int -> ScalarStyle -> ShowS
[ScalarStyle] -> ShowS
ScalarStyle -> String
(Int -> ScalarStyle -> ShowS)
-> (ScalarStyle -> String)
-> ([ScalarStyle] -> ShowS)
-> Show ScalarStyle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ScalarStyle -> ShowS
showsPrec :: Int -> ScalarStyle -> ShowS
$cshow :: ScalarStyle -> String
show :: ScalarStyle -> String
$cshowList :: [ScalarStyle] -> ShowS
showList :: [ScalarStyle] -> ShowS
Show, Int -> ScalarStyle
ScalarStyle -> Int
ScalarStyle -> [ScalarStyle]
ScalarStyle -> ScalarStyle
ScalarStyle -> ScalarStyle -> [ScalarStyle]
ScalarStyle -> ScalarStyle -> ScalarStyle -> [ScalarStyle]
(ScalarStyle -> ScalarStyle)
-> (ScalarStyle -> ScalarStyle)
-> (Int -> ScalarStyle)
-> (ScalarStyle -> Int)
-> (ScalarStyle -> [ScalarStyle])
-> (ScalarStyle -> ScalarStyle -> [ScalarStyle])
-> (ScalarStyle -> ScalarStyle -> [ScalarStyle])
-> (ScalarStyle -> ScalarStyle -> ScalarStyle -> [ScalarStyle])
-> Enum ScalarStyle
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: ScalarStyle -> ScalarStyle
succ :: ScalarStyle -> ScalarStyle
$cpred :: ScalarStyle -> ScalarStyle
pred :: ScalarStyle -> ScalarStyle
$ctoEnum :: Int -> ScalarStyle
toEnum :: Int -> ScalarStyle
$cfromEnum :: ScalarStyle -> Int
fromEnum :: ScalarStyle -> Int
$cenumFrom :: ScalarStyle -> [ScalarStyle]
enumFrom :: ScalarStyle -> [ScalarStyle]
$cenumFromThen :: ScalarStyle -> ScalarStyle -> [ScalarStyle]
enumFromThen :: ScalarStyle -> ScalarStyle -> [ScalarStyle]
$cenumFromTo :: ScalarStyle -> ScalarStyle -> [ScalarStyle]
enumFromTo :: ScalarStyle -> ScalarStyle -> [ScalarStyle]
$cenumFromThenTo :: ScalarStyle -> ScalarStyle -> ScalarStyle -> [ScalarStyle]
enumFromThenTo :: ScalarStyle -> ScalarStyle -> ScalarStyle -> [ScalarStyle]
Enum, ScalarStyle
ScalarStyle -> ScalarStyle -> Bounded ScalarStyle
forall a. a -> a -> Bounded a
$cminBound :: ScalarStyle
minBound :: ScalarStyle
$cmaxBound :: ScalarStyle
maxBound :: ScalarStyle
Bounded, (forall x. ScalarStyle -> Rep ScalarStyle x)
-> (forall x. Rep ScalarStyle x -> ScalarStyle)
-> Generic ScalarStyle
forall x. Rep ScalarStyle x -> ScalarStyle
forall x. ScalarStyle -> Rep ScalarStyle x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ScalarStyle -> Rep ScalarStyle x
from :: forall x. ScalarStyle -> Rep ScalarStyle x
$cto :: forall x. Rep ScalarStyle x -> ScalarStyle
to :: forall x. Rep ScalarStyle x -> ScalarStyle
Generic)

instance NFData ScalarStyle where
  rnf :: ScalarStyle -> ()
rnf = ScalarStyle -> ()
forall a. a -> ()
rwhnf

-- | The literal or the folded style.
isBlockScalar :: ScalarStyle -> Bool
isBlockScalar :: ScalarStyle -> Bool
isBlockScalar ScalarStyle
s = ScalarStyle
s ScalarStyle -> ScalarStyle -> Bool
forall a. Eq a => a -> a -> Bool
== ScalarStyle
Literal Bool -> Bool -> Bool
|| ScalarStyle
s ScalarStyle -> ScalarStyle -> Bool
forall a. Eq a => a -> a -> Bool
== ScalarStyle
Folded

-- | The style of a collection: with indentation, or with brackets and commas.
data CollectionStyle
  = Block
  | Flow
  deriving stock (CollectionStyle -> CollectionStyle -> Bool
(CollectionStyle -> CollectionStyle -> Bool)
-> (CollectionStyle -> CollectionStyle -> Bool)
-> Eq CollectionStyle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CollectionStyle -> CollectionStyle -> Bool
== :: CollectionStyle -> CollectionStyle -> Bool
$c/= :: CollectionStyle -> CollectionStyle -> Bool
/= :: CollectionStyle -> CollectionStyle -> Bool
Eq, Eq CollectionStyle
Eq CollectionStyle =>
(CollectionStyle -> CollectionStyle -> Ordering)
-> (CollectionStyle -> CollectionStyle -> Bool)
-> (CollectionStyle -> CollectionStyle -> Bool)
-> (CollectionStyle -> CollectionStyle -> Bool)
-> (CollectionStyle -> CollectionStyle -> Bool)
-> (CollectionStyle -> CollectionStyle -> CollectionStyle)
-> (CollectionStyle -> CollectionStyle -> CollectionStyle)
-> Ord CollectionStyle
CollectionStyle -> CollectionStyle -> Bool
CollectionStyle -> CollectionStyle -> Ordering
CollectionStyle -> CollectionStyle -> CollectionStyle
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 :: CollectionStyle -> CollectionStyle -> Ordering
compare :: CollectionStyle -> CollectionStyle -> Ordering
$c< :: CollectionStyle -> CollectionStyle -> Bool
< :: CollectionStyle -> CollectionStyle -> Bool
$c<= :: CollectionStyle -> CollectionStyle -> Bool
<= :: CollectionStyle -> CollectionStyle -> Bool
$c> :: CollectionStyle -> CollectionStyle -> Bool
> :: CollectionStyle -> CollectionStyle -> Bool
$c>= :: CollectionStyle -> CollectionStyle -> Bool
>= :: CollectionStyle -> CollectionStyle -> Bool
$cmax :: CollectionStyle -> CollectionStyle -> CollectionStyle
max :: CollectionStyle -> CollectionStyle -> CollectionStyle
$cmin :: CollectionStyle -> CollectionStyle -> CollectionStyle
min :: CollectionStyle -> CollectionStyle -> CollectionStyle
Ord, Int -> CollectionStyle -> ShowS
[CollectionStyle] -> ShowS
CollectionStyle -> String
(Int -> CollectionStyle -> ShowS)
-> (CollectionStyle -> String)
-> ([CollectionStyle] -> ShowS)
-> Show CollectionStyle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CollectionStyle -> ShowS
showsPrec :: Int -> CollectionStyle -> ShowS
$cshow :: CollectionStyle -> String
show :: CollectionStyle -> String
$cshowList :: [CollectionStyle] -> ShowS
showList :: [CollectionStyle] -> ShowS
Show, Int -> CollectionStyle
CollectionStyle -> Int
CollectionStyle -> [CollectionStyle]
CollectionStyle -> CollectionStyle
CollectionStyle -> CollectionStyle -> [CollectionStyle]
CollectionStyle
-> CollectionStyle -> CollectionStyle -> [CollectionStyle]
(CollectionStyle -> CollectionStyle)
-> (CollectionStyle -> CollectionStyle)
-> (Int -> CollectionStyle)
-> (CollectionStyle -> Int)
-> (CollectionStyle -> [CollectionStyle])
-> (CollectionStyle -> CollectionStyle -> [CollectionStyle])
-> (CollectionStyle -> CollectionStyle -> [CollectionStyle])
-> (CollectionStyle
    -> CollectionStyle -> CollectionStyle -> [CollectionStyle])
-> Enum CollectionStyle
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: CollectionStyle -> CollectionStyle
succ :: CollectionStyle -> CollectionStyle
$cpred :: CollectionStyle -> CollectionStyle
pred :: CollectionStyle -> CollectionStyle
$ctoEnum :: Int -> CollectionStyle
toEnum :: Int -> CollectionStyle
$cfromEnum :: CollectionStyle -> Int
fromEnum :: CollectionStyle -> Int
$cenumFrom :: CollectionStyle -> [CollectionStyle]
enumFrom :: CollectionStyle -> [CollectionStyle]
$cenumFromThen :: CollectionStyle -> CollectionStyle -> [CollectionStyle]
enumFromThen :: CollectionStyle -> CollectionStyle -> [CollectionStyle]
$cenumFromTo :: CollectionStyle -> CollectionStyle -> [CollectionStyle]
enumFromTo :: CollectionStyle -> CollectionStyle -> [CollectionStyle]
$cenumFromThenTo :: CollectionStyle
-> CollectionStyle -> CollectionStyle -> [CollectionStyle]
enumFromThenTo :: CollectionStyle
-> CollectionStyle -> CollectionStyle -> [CollectionStyle]
Enum, CollectionStyle
CollectionStyle -> CollectionStyle -> Bounded CollectionStyle
forall a. a -> a -> Bounded a
$cminBound :: CollectionStyle
minBound :: CollectionStyle
$cmaxBound :: CollectionStyle
maxBound :: CollectionStyle
Bounded, (forall x. CollectionStyle -> Rep CollectionStyle x)
-> (forall x. Rep CollectionStyle x -> CollectionStyle)
-> Generic CollectionStyle
forall x. Rep CollectionStyle x -> CollectionStyle
forall x. CollectionStyle -> Rep CollectionStyle x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CollectionStyle -> Rep CollectionStyle x
from :: forall x. CollectionStyle -> Rep CollectionStyle x
$cto :: forall x. Rep CollectionStyle x -> CollectionStyle
to :: forall x. Rep CollectionStyle x -> CollectionStyle
Generic)

instance NFData CollectionStyle where
  rnf :: CollectionStyle -> ()
rnf = CollectionStyle -> ()
forall a. a -> ()
rwhnf

-- | A node with the given content, without properties and comments.
contentNode :: Content -> Node
contentNode :: Content -> Node
contentNode Content
c =
  Node
    { offset :: Offset
offset = Offset
noOffset
    , endOffset :: Offset
endOffset = Offset
noOffset
    , props :: Props
props = Props
noProps
    , comments :: Comments
comments = Comments
noComments
    , content :: Content
content = Content
c
    }

-- | A scalar in the given style. 'Yamlet.Syntax.renderSyntax' uses quotes if
-- the style cannot hold the text, and for a block scalar that is a key or an
-- entry of a flow collection.
--
-- >>> T.putStr (renderSyntax defaultRenderOptions [document (mappingNode [(plainNode "key", scalarNode Plain "a: b")])])
-- key: 'a: b'
scalarNode :: ScalarStyle -> T.Text -> Node
scalarNode :: ScalarStyle -> Text -> Node
scalarNode ScalarStyle
style = Content -> Node
contentNode (Content -> Node) -> (Text -> Content) -> Text -> Node
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScalarStyle -> Text -> Content
ScalarContent ScalarStyle
style

-- | A plain scalar.
plainNode :: T.Text -> Node
plainNode :: Text -> Node
plainNode = ScalarStyle -> Text -> Node
scalarNode ScalarStyle
Plain

-- | A block sequence.
sequenceNode :: [Node] -> Node
sequenceNode :: [Node] -> Node
sequenceNode = Content -> Node
contentNode (Content -> Node) -> ([Node] -> Content) -> [Node] -> Node
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CollectionStyle -> [Node] -> Content
SequenceContent CollectionStyle
Block

-- | A block mapping.
mappingNode :: [(Node, Node)] -> Node
mappingNode :: [(Node, Node)] -> Node
mappingNode = Content -> Node
contentNode (Content -> Node)
-> ([(Node, Node)] -> Content) -> [(Node, Node)] -> Node
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CollectionStyle -> [(Node, Node)] -> Content
MappingContent CollectionStyle
Block

-- | The comments and the empty lines that belong to a node.
data Comments = Comments
  { Comments -> [Line]
before :: ![Line]
  -- ^ The lines above the node.
  , Comments -> Maybe Text
inline :: !(Maybe T.Text)
  -- ^ The comment at the end of the line where the node ends, or of the
  -- first line of a block collection or a block scalar. The renderer
  -- writes each line break in it as a space. The line breaks are the
  -- characters that 'CommentLine' lists.
  , Comments -> [Line]
after :: ![Line]
  -- ^ The lines below the node: after the last entry of a collection,
  -- between the brackets of an empty collection, or below a scalar or an
  -- alias in a block collection or at the root. The section
  -- [Comments]("Yamlet.Syntax#comments") gives the rules. The renderer
  -- writes such lines below any node.
  }
  deriving stock (Comments -> Comments -> Bool
(Comments -> Comments -> Bool)
-> (Comments -> Comments -> Bool) -> Eq Comments
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Comments -> Comments -> Bool
== :: Comments -> Comments -> Bool
$c/= :: Comments -> Comments -> Bool
/= :: Comments -> Comments -> Bool
Eq, Eq Comments
Eq Comments =>
(Comments -> Comments -> Ordering)
-> (Comments -> Comments -> Bool)
-> (Comments -> Comments -> Bool)
-> (Comments -> Comments -> Bool)
-> (Comments -> Comments -> Bool)
-> (Comments -> Comments -> Comments)
-> (Comments -> Comments -> Comments)
-> Ord Comments
Comments -> Comments -> Bool
Comments -> Comments -> Ordering
Comments -> Comments -> Comments
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 :: Comments -> Comments -> Ordering
compare :: Comments -> Comments -> Ordering
$c< :: Comments -> Comments -> Bool
< :: Comments -> Comments -> Bool
$c<= :: Comments -> Comments -> Bool
<= :: Comments -> Comments -> Bool
$c> :: Comments -> Comments -> Bool
> :: Comments -> Comments -> Bool
$c>= :: Comments -> Comments -> Bool
>= :: Comments -> Comments -> Bool
$cmax :: Comments -> Comments -> Comments
max :: Comments -> Comments -> Comments
$cmin :: Comments -> Comments -> Comments
min :: Comments -> Comments -> Comments
Ord, Int -> Comments -> ShowS
[Comments] -> ShowS
Comments -> String
(Int -> Comments -> ShowS)
-> (Comments -> String) -> ([Comments] -> ShowS) -> Show Comments
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Comments -> ShowS
showsPrec :: Int -> Comments -> ShowS
$cshow :: Comments -> String
show :: Comments -> String
$cshowList :: [Comments] -> ShowS
showList :: [Comments] -> ShowS
Show, (forall x. Comments -> Rep Comments x)
-> (forall x. Rep Comments x -> Comments) -> Generic Comments
forall x. Rep Comments x -> Comments
forall x. Comments -> Rep Comments x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Comments -> Rep Comments x
from :: forall x. Comments -> Rep Comments x
$cto :: forall x. Rep Comments x -> Comments
to :: forall x. Rep Comments x -> Comments
Generic)
  deriving anyclass (Comments -> ()
(Comments -> ()) -> NFData Comments
forall a. (a -> ()) -> NFData a
$crnf :: Comments -> ()
rnf :: Comments -> ()
NFData)

-- | No comments and no empty lines.
noComments :: Comments
noComments :: Comments
noComments = Comments {before :: [Line]
before = [], inline :: Maybe Text
inline = Maybe Text
forall a. Maybe a
Nothing, after :: [Line]
after = []}

-- | The node with the comments in place of its own. A record update of the
-- field is ambiguous where t'Commented' is in scope.
withComments :: Comments -> Node -> Node
withComments :: Comments -> Node -> Node
withComments Comments
c Node
n =
  Node
    { offset :: Offset
offset = Node
n.offset
    , endOffset :: Offset
endOffset = Node
n.endOffset
    , props :: Props
props = Node
n.props
    , comments :: Comments
comments = Comments
c
    , content :: Content
content = Node
n.content
    }

-- | A value with the comments of its mapping entry:
--
-- * 'Yamlet.Syntax.before': the lines above the entry,
--
-- * 'Yamlet.Syntax.inline': the comment at the end of the line of the key,
--   or of the line where a value on several lines ends,
--
-- * 'Yamlet.Syntax.after': the lines after the value, e.g. after the last
--   entry of a collection.
--
-- A t'Commented' value of a mapping entry has the comments of the entry. A
-- block list or mapping under the key has its own comments: the lines below
-- the key up to the last empty line above its first entry. A t'Commented'
-- value inside the first one keeps them, so a type that keeps both nests two
-- t'Commented' values:
--
-- >>> input = "# The CI jobs.\njobs:\n  # Run on every push.\n\n  # Check the formatting.\n  - lint\n"
--
-- >>> T.putStr input
-- # The CI jobs.
-- jobs:
--   # Run on every push.
-- <BLANKLINE>
--   # Check the formatting.
--   - lint
--
-- >>> Right entries = decodeText @(M.Map T.Text (Commented (Commented [Commented T.Text]))) input
-- >>> Just jobs = M.lookup "jobs" entries
--
-- >>> jobs.comments
-- Comments {before = [Comment "The CI jobs."], inline = Nothing, after = []}
--
-- >>> jobs.value.comments
-- Comments {before = [Comment "Run on every push.",EmptyLine], inline = Nothing, after = []}
--
-- >>> map (.comments) jobs.value.value
-- [Comments {before = [Comment "Check the formatting."], inline = Nothing, after = []}]
--
-- A value without a key, e.g. an item of a list, has the comments of its
-- node. The comments of a list or a mapping stay with it, not with its first
-- item or key: the lines up to the last empty line above its first entry, and
-- the comment on its first line, e.g. after its tag. A t'Commented' value of
-- the whole list or mapping keeps them.
--
-- By the rules in [Comments]("Yamlet.Syntax#comments"), some lines read
-- back with a change:
--
-- * The lines after a text of several lines, which the encoder writes as a
--   block scalar, read back as the lines above the next entry. After the
--   last entry, they belong to the end of the collection around the entry.
--
-- * The lines above a list or a mapping without a key can get an empty line
--   below them, e.g. at the top level. The empty line reads back as the last
--   of these lines.
--
-- * The lines above the first item of a list or the first key of a mapping
--   that end with an empty line read back as the lines of the list or the
--   mapping. A t'Commented' list or mapping keeps them. Under a key, the
--   inner of two nested t'Commented' values keeps them, as above. Otherwise
--   they are lost.
--
-- A comment is lost if its node has no place for it, i.e. if the node does
-- not decode into a node or a t'Commented' value:
--
-- * the comments of a key without a Haskell field, e.g. the tag of a
--   constructor;
--
-- * a comment at the end of a nested mapping, unless the field that holds
--   the mapping is t'Commented', because a record has no place for the end
--   of its mapping;
--
-- * the comments of a record's mapping above its first key, e.g. a comment
--   at the top of a file above an empty line;
--
-- * the comments of the key for a type such as
--   @data Name = Name (Commented Text)@ that derives its instances through
--   'Generic', because a derived instance for one constructor with one field
--   without a name does not give the key of its entry to the value inside.
--   Declare such a type as a newtype and derive its instances with
--   @deriving newtype@, which gives the key to the value.
--
-- In a map, use t'Commented' on the key or on the value, not on both. With
-- both, the decoder gives the comments of the key to both, and the encoder
-- writes only those of the value, so a change to the comments of the key is
-- lost.
--
-- A change of the value keeps the comments:
--
-- >>> input = "# The port.\nport: 80 # the default\n"
--
-- >>> :{
-- either printErrors (T.putStr . encodeText . M.map (fmap (+ 1))) $
--   decodeText @(M.Map T.Text (Commented Int)) input
-- :}
-- # The port.
-- port: 81 # the default
--
-- The order compares the values first and then the comments, e.g. in a set.
data Commented a = Commented
  { forall a. Commented a -> a
value :: !a
  , forall a. Commented a -> Comments
comments :: !Comments
  }
  -- The derived order compares the fields in this order.
  deriving stock (Commented a -> Commented a -> Bool
(Commented a -> Commented a -> Bool)
-> (Commented a -> Commented a -> Bool) -> Eq (Commented a)
forall a. Eq a => Commented a -> Commented a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Commented a -> Commented a -> Bool
== :: Commented a -> Commented a -> Bool
$c/= :: forall a. Eq a => Commented a -> Commented a -> Bool
/= :: Commented a -> Commented a -> Bool
Eq, Eq (Commented a)
Eq (Commented a) =>
(Commented a -> Commented a -> Ordering)
-> (Commented a -> Commented a -> Bool)
-> (Commented a -> Commented a -> Bool)
-> (Commented a -> Commented a -> Bool)
-> (Commented a -> Commented a -> Bool)
-> (Commented a -> Commented a -> Commented a)
-> (Commented a -> Commented a -> Commented a)
-> Ord (Commented a)
Commented a -> Commented a -> Bool
Commented a -> Commented a -> Ordering
Commented a -> Commented a -> Commented a
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
forall a. Ord a => Eq (Commented a)
forall a. Ord a => Commented a -> Commented a -> Bool
forall a. Ord a => Commented a -> Commented a -> Ordering
forall a. Ord a => Commented a -> Commented a -> Commented a
$ccompare :: forall a. Ord a => Commented a -> Commented a -> Ordering
compare :: Commented a -> Commented a -> Ordering
$c< :: forall a. Ord a => Commented a -> Commented a -> Bool
< :: Commented a -> Commented a -> Bool
$c<= :: forall a. Ord a => Commented a -> Commented a -> Bool
<= :: Commented a -> Commented a -> Bool
$c> :: forall a. Ord a => Commented a -> Commented a -> Bool
> :: Commented a -> Commented a -> Bool
$c>= :: forall a. Ord a => Commented a -> Commented a -> Bool
>= :: Commented a -> Commented a -> Bool
$cmax :: forall a. Ord a => Commented a -> Commented a -> Commented a
max :: Commented a -> Commented a -> Commented a
$cmin :: forall a. Ord a => Commented a -> Commented a -> Commented a
min :: Commented a -> Commented a -> Commented a
Ord, Int -> Commented a -> ShowS
[Commented a] -> ShowS
Commented a -> String
(Int -> Commented a -> ShowS)
-> (Commented a -> String)
-> ([Commented a] -> ShowS)
-> Show (Commented a)
forall a. Show a => Int -> Commented a -> ShowS
forall a. Show a => [Commented a] -> ShowS
forall a. Show a => Commented a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Commented a -> ShowS
showsPrec :: Int -> Commented a -> ShowS
$cshow :: forall a. Show a => Commented a -> String
show :: Commented a -> String
$cshowList :: forall a. Show a => [Commented a] -> ShowS
showList :: [Commented a] -> ShowS
Show, (forall a b. (a -> b) -> Commented a -> Commented b)
-> (forall a b. a -> Commented b -> Commented a)
-> Functor Commented
forall a b. a -> Commented b -> Commented a
forall a b. (a -> b) -> Commented a -> Commented b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Commented a -> Commented b
fmap :: forall a b. (a -> b) -> Commented a -> Commented b
$c<$ :: forall a b. a -> Commented b -> Commented a
<$ :: forall a b. a -> Commented b -> Commented a
Functor, (forall m. Monoid m => Commented m -> m)
-> (forall m a. Monoid m => (a -> m) -> Commented a -> m)
-> (forall m a. Monoid m => (a -> m) -> Commented a -> m)
-> (forall a b. (a -> b -> b) -> b -> Commented a -> b)
-> (forall a b. (a -> b -> b) -> b -> Commented a -> b)
-> (forall b a. (b -> a -> b) -> b -> Commented a -> b)
-> (forall b a. (b -> a -> b) -> b -> Commented a -> b)
-> (forall a. (a -> a -> a) -> Commented a -> a)
-> (forall a. (a -> a -> a) -> Commented a -> a)
-> (forall a. Commented a -> [a])
-> (forall a. Commented a -> Bool)
-> (forall a. Commented a -> Int)
-> (forall a. Eq a => a -> Commented a -> Bool)
-> (forall a. Ord a => Commented a -> a)
-> (forall a. Ord a => Commented a -> a)
-> (forall a. Num a => Commented a -> a)
-> (forall a. Num a => Commented a -> a)
-> Foldable Commented
forall a. Eq a => a -> Commented a -> Bool
forall a. Num a => Commented a -> a
forall a. Ord a => Commented a -> a
forall m. Monoid m => Commented m -> m
forall a. Commented a -> Bool
forall a. Commented a -> Int
forall a. Commented a -> [a]
forall a. (a -> a -> a) -> Commented a -> a
forall m a. Monoid m => (a -> m) -> Commented a -> m
forall b a. (b -> a -> b) -> b -> Commented a -> b
forall a b. (a -> b -> b) -> b -> Commented a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Commented m -> m
fold :: forall m. Monoid m => Commented m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Commented a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Commented a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Commented a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Commented a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Commented a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Commented a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Commented a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Commented a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Commented a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Commented a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Commented a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Commented a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Commented a -> a
foldr1 :: forall a. (a -> a -> a) -> Commented a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Commented a -> a
foldl1 :: forall a. (a -> a -> a) -> Commented a -> a
$ctoList :: forall a. Commented a -> [a]
toList :: forall a. Commented a -> [a]
$cnull :: forall a. Commented a -> Bool
null :: forall a. Commented a -> Bool
$clength :: forall a. Commented a -> Int
length :: forall a. Commented a -> Int
$celem :: forall a. Eq a => a -> Commented a -> Bool
elem :: forall a. Eq a => a -> Commented a -> Bool
$cmaximum :: forall a. Ord a => Commented a -> a
maximum :: forall a. Ord a => Commented a -> a
$cminimum :: forall a. Ord a => Commented a -> a
minimum :: forall a. Ord a => Commented a -> a
$csum :: forall a. Num a => Commented a -> a
sum :: forall a. Num a => Commented a -> a
$cproduct :: forall a. Num a => Commented a -> a
product :: forall a. Num a => Commented a -> a
Foldable, Functor Commented
Foldable Commented
(Functor Commented, Foldable Commented) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Commented a -> f (Commented b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Commented (f a) -> f (Commented a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Commented a -> m (Commented b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Commented (m a) -> m (Commented a))
-> Traversable Commented
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
Commented (m a) -> m (Commented a)
forall (f :: * -> *) a.
Applicative f =>
Commented (f a) -> f (Commented a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Commented a -> m (Commented b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Commented a -> f (Commented b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Commented a -> f (Commented b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Commented a -> f (Commented b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Commented (f a) -> f (Commented a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Commented (f a) -> f (Commented a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Commented a -> m (Commented b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Commented a -> m (Commented b)
$csequence :: forall (m :: * -> *) a.
Monad m =>
Commented (m a) -> m (Commented a)
sequence :: forall (m :: * -> *) a.
Monad m =>
Commented (m a) -> m (Commented a)
Traversable, (forall x. Commented a -> Rep (Commented a) x)
-> (forall x. Rep (Commented a) x -> Commented a)
-> Generic (Commented a)
forall x. Rep (Commented a) x -> Commented a
forall x. Commented a -> Rep (Commented a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Commented a) x -> Commented a
forall a x. Commented a -> Rep (Commented a) x
$cfrom :: forall a x. Commented a -> Rep (Commented a) x
from :: forall x. Commented a -> Rep (Commented a) x
$cto :: forall a x. Rep (Commented a) x -> Commented a
to :: forall x. Rep (Commented a) x -> Commented a
Generic)
  deriving anyclass (Commented a -> ()
(Commented a -> ()) -> NFData (Commented a)
forall a. NFData a => Commented a -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall a. NFData a => Commented a -> ()
rnf :: Commented a -> ()
NFData)

-- | A value with the offset of its node, e.g. for the error of a check that
-- runs after the decode. The encoder writes only the value.
--
-- 'Yamlet.Error.documentErrors' turns the offsets into errors with lines,
-- columns and paths. It needs the text and the document of the decode, so
-- decode with 'Yamlet.decodeWithDocument'. Here the check gives an offset and
-- a message for each problem:
--
-- >>> input = "paths:\n- src\n- /etc\n"
--
-- >>> :{
-- case decodeWithDocument @(M.Map T.Text [Located T.Text]) input of
--   Right (config, doc) ->
--     let errs =
--           [ (p.offset, "the path is outside the repository")
--           | p <- concat (M.elems config)
--           , "/" `T.isPrefixOf` p.value
--           ]
--     in printErrors (documentErrors input doc errs)
--   Left errs -> printErrors errs
-- :}
-- input.yaml:3:3: paths[1]: the path is outside the repository
--   |
-- 3 | - /etc
--   |   ^
--
-- A value that no node gives, e.g. a value of 'Yamlet.Generic.yamlDefault',
-- has 'noOffset'. Its error has no position, and 'Yamlet.Error.prettyError'
-- prints only the file and the message. A value inside an alias has the
-- offset of the alias, i.e. of the place where the document uses the value.
--
-- Two equal values at different places are not equal as t'Located' values,
-- e.g. a set keeps both. The equality and the order compare the values first
-- and then the offsets. To compare only the values, e.g. in a test, use the
-- field @value@.
data Located a = Located
  { forall a. Located a -> a
value :: !a
  , forall a. Located a -> Offset
offset :: !Offset
  }
  -- The derived order compares the fields in this order.
  deriving stock (Located a -> Located a -> Bool
(Located a -> Located a -> Bool)
-> (Located a -> Located a -> Bool) -> Eq (Located a)
forall a. Eq a => Located a -> Located a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Located a -> Located a -> Bool
== :: Located a -> Located a -> Bool
$c/= :: forall a. Eq a => Located a -> Located a -> Bool
/= :: Located a -> Located a -> Bool
Eq, Eq (Located a)
Eq (Located a) =>
(Located a -> Located a -> Ordering)
-> (Located a -> Located a -> Bool)
-> (Located a -> Located a -> Bool)
-> (Located a -> Located a -> Bool)
-> (Located a -> Located a -> Bool)
-> (Located a -> Located a -> Located a)
-> (Located a -> Located a -> Located a)
-> Ord (Located a)
Located a -> Located a -> Bool
Located a -> Located a -> Ordering
Located a -> Located a -> Located a
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
forall a. Ord a => Eq (Located a)
forall a. Ord a => Located a -> Located a -> Bool
forall a. Ord a => Located a -> Located a -> Ordering
forall a. Ord a => Located a -> Located a -> Located a
$ccompare :: forall a. Ord a => Located a -> Located a -> Ordering
compare :: Located a -> Located a -> Ordering
$c< :: forall a. Ord a => Located a -> Located a -> Bool
< :: Located a -> Located a -> Bool
$c<= :: forall a. Ord a => Located a -> Located a -> Bool
<= :: Located a -> Located a -> Bool
$c> :: forall a. Ord a => Located a -> Located a -> Bool
> :: Located a -> Located a -> Bool
$c>= :: forall a. Ord a => Located a -> Located a -> Bool
>= :: Located a -> Located a -> Bool
$cmax :: forall a. Ord a => Located a -> Located a -> Located a
max :: Located a -> Located a -> Located a
$cmin :: forall a. Ord a => Located a -> Located a -> Located a
min :: Located a -> Located a -> Located a
Ord, Int -> Located a -> ShowS
[Located a] -> ShowS
Located a -> String
(Int -> Located a -> ShowS)
-> (Located a -> String)
-> ([Located a] -> ShowS)
-> Show (Located a)
forall a. Show a => Int -> Located a -> ShowS
forall a. Show a => [Located a] -> ShowS
forall a. Show a => Located a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Located a -> ShowS
showsPrec :: Int -> Located a -> ShowS
$cshow :: forall a. Show a => Located a -> String
show :: Located a -> String
$cshowList :: forall a. Show a => [Located a] -> ShowS
showList :: [Located a] -> ShowS
Show, (forall a b. (a -> b) -> Located a -> Located b)
-> (forall a b. a -> Located b -> Located a) -> Functor Located
forall a b. a -> Located b -> Located a
forall a b. (a -> b) -> Located a -> Located b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Located a -> Located b
fmap :: forall a b. (a -> b) -> Located a -> Located b
$c<$ :: forall a b. a -> Located b -> Located a
<$ :: forall a b. a -> Located b -> Located a
Functor, (forall m. Monoid m => Located m -> m)
-> (forall m a. Monoid m => (a -> m) -> Located a -> m)
-> (forall m a. Monoid m => (a -> m) -> Located a -> m)
-> (forall a b. (a -> b -> b) -> b -> Located a -> b)
-> (forall a b. (a -> b -> b) -> b -> Located a -> b)
-> (forall b a. (b -> a -> b) -> b -> Located a -> b)
-> (forall b a. (b -> a -> b) -> b -> Located a -> b)
-> (forall a. (a -> a -> a) -> Located a -> a)
-> (forall a. (a -> a -> a) -> Located a -> a)
-> (forall a. Located a -> [a])
-> (forall a. Located a -> Bool)
-> (forall a. Located a -> Int)
-> (forall a. Eq a => a -> Located a -> Bool)
-> (forall a. Ord a => Located a -> a)
-> (forall a. Ord a => Located a -> a)
-> (forall a. Num a => Located a -> a)
-> (forall a. Num a => Located a -> a)
-> Foldable Located
forall a. Eq a => a -> Located a -> Bool
forall a. Num a => Located a -> a
forall a. Ord a => Located a -> a
forall m. Monoid m => Located m -> m
forall a. Located a -> Bool
forall a. Located a -> Int
forall a. Located a -> [a]
forall a. (a -> a -> a) -> Located a -> a
forall m a. Monoid m => (a -> m) -> Located a -> m
forall b a. (b -> a -> b) -> b -> Located a -> b
forall a b. (a -> b -> b) -> b -> Located a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Located m -> m
fold :: forall m. Monoid m => Located m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Located a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Located a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Located a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Located a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Located a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Located a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Located a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Located a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Located a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Located a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Located a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Located a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Located a -> a
foldr1 :: forall a. (a -> a -> a) -> Located a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Located a -> a
foldl1 :: forall a. (a -> a -> a) -> Located a -> a
$ctoList :: forall a. Located a -> [a]
toList :: forall a. Located a -> [a]
$cnull :: forall a. Located a -> Bool
null :: forall a. Located a -> Bool
$clength :: forall a. Located a -> Int
length :: forall a. Located a -> Int
$celem :: forall a. Eq a => a -> Located a -> Bool
elem :: forall a. Eq a => a -> Located a -> Bool
$cmaximum :: forall a. Ord a => Located a -> a
maximum :: forall a. Ord a => Located a -> a
$cminimum :: forall a. Ord a => Located a -> a
minimum :: forall a. Ord a => Located a -> a
$csum :: forall a. Num a => Located a -> a
sum :: forall a. Num a => Located a -> a
$cproduct :: forall a. Num a => Located a -> a
product :: forall a. Num a => Located a -> a
Foldable, Functor Located
Foldable Located
(Functor Located, Foldable Located) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Located a -> f (Located b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Located (f a) -> f (Located a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Located a -> m (Located b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Located (m a) -> m (Located a))
-> Traversable Located
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Located (m a) -> m (Located a)
forall (f :: * -> *) a.
Applicative f =>
Located (f a) -> f (Located a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Located a -> m (Located b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Located a -> f (Located b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Located a -> f (Located b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Located a -> f (Located b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Located (f a) -> f (Located a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Located (f a) -> f (Located a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Located a -> m (Located b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Located a -> m (Located b)
$csequence :: forall (m :: * -> *) a. Monad m => Located (m a) -> m (Located a)
sequence :: forall (m :: * -> *) a. Monad m => Located (m a) -> m (Located a)
Traversable, (forall x. Located a -> Rep (Located a) x)
-> (forall x. Rep (Located a) x -> Located a)
-> Generic (Located a)
forall x. Rep (Located a) x -> Located a
forall x. Located a -> Rep (Located a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Located a) x -> Located a
forall a x. Located a -> Rep (Located a) x
$cfrom :: forall a x. Located a -> Rep (Located a) x
from :: forall x. Located a -> Rep (Located a) x
$cto :: forall a x. Rep (Located a) x -> Located a
to :: forall x. Rep (Located a) x -> Located a
Generic)
  deriving anyclass (Located a -> ()
(Located a -> ()) -> NFData (Located a)
forall a. NFData a => Located a -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall a. NFData a => Located a -> ()
rnf :: Located a -> ()
NFData)

-- | A line of comments.
data Line
  = EmptyLine
  | -- | The number of @#@ characters at the start of the comment, e.g. 2 for
    -- @## Section@, and the text after them, without the one space after the
    -- @#@ characters and without the white space at its end. The renderer
    -- writes a count below 1 as 1. It writes a text with line breaks as
    -- several comment lines with the same @#@ characters, and the parser
    -- reads them back as several comments. U+0085, U+2028 and U+2029 count as
    -- line breaks here, because YAML 1.1 reads them as line breaks.
    --
    -- The comment at the end of a line in t'Comments' is a text without a
    -- count. It keeps the @#@ characters after the first one in its text.
    CommentLine !Int !T.Text
  deriving stock (Line -> Line -> Bool
(Line -> Line -> Bool) -> (Line -> Line -> Bool) -> Eq Line
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Line -> Line -> Bool
== :: Line -> Line -> Bool
$c/= :: Line -> Line -> Bool
/= :: Line -> Line -> Bool
Eq, Eq Line
Eq Line =>
(Line -> Line -> Ordering)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Bool)
-> (Line -> Line -> Line)
-> (Line -> Line -> Line)
-> Ord Line
Line -> Line -> Bool
Line -> Line -> Ordering
Line -> Line -> Line
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 :: Line -> Line -> Ordering
compare :: Line -> Line -> Ordering
$c< :: Line -> Line -> Bool
< :: Line -> Line -> Bool
$c<= :: Line -> Line -> Bool
<= :: Line -> Line -> Bool
$c> :: Line -> Line -> Bool
> :: Line -> Line -> Bool
$c>= :: Line -> Line -> Bool
>= :: Line -> Line -> Bool
$cmax :: Line -> Line -> Line
max :: Line -> Line -> Line
$cmin :: Line -> Line -> Line
min :: Line -> Line -> Line
Ord, (forall x. Line -> Rep Line x)
-> (forall x. Rep Line x -> Line) -> Generic Line
forall x. Rep Line x -> Line
forall x. Line -> Rep Line x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Line -> Rep Line x
from :: forall x. Line -> Rep Line x
$cto :: forall x. Rep Line x -> Line
to :: forall x. Rep Line x -> Line
Generic)

-- | A comment with one @#@. As a pattern, it matches every comment and
-- ignores the number of @#@ characters.
pattern Comment :: T.Text -> Line
pattern $bComment :: Text -> Line
$mComment :: forall {r}. Line -> (Text -> r) -> ((# #) -> r) -> r
Comment t <- CommentLine _ t
  where
    Comment Text
t = Int -> Text -> Line
CommentLine Int
1 Text
t

{-# COMPLETE EmptyLine, Comment #-}

-- A comment with one @#@ shows as 'Comment', as a program usually writes it.
instance Show Line where
  showsPrec :: Int -> Line -> ShowS
showsPrec Int
d = \case
    Line
EmptyLine -> String -> ShowS
showString String
"EmptyLine"
    CommentLine Int
1 Text
t -> Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString String
"Comment " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Text -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Text
t
    CommentLine Int
n Text
t ->
      Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
        String -> ShowS
showString String
"CommentLine " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Int
n ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Text -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Text
t

instance NFData Line where
  rnf :: Line -> ()
rnf = Line -> ()
forall a. a -> ()
rwhnf

-- | The offset of a byte in the input text, in its UTF-8 encoding. For an
-- input in UTF-16 or UTF-32, the offset counts the bytes of the text after
-- 'Yamlet.Syntax.decodeInput', not the bytes of the input.
newtype Offset = Offset Int
  deriving stock ((forall x. Offset -> Rep Offset x)
-> (forall x. Rep Offset x -> Offset) -> Generic Offset
forall x. Rep Offset x -> Offset
forall x. Offset -> Rep Offset x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Offset -> Rep Offset x
from :: forall x. Offset -> Rep Offset x
$cto :: forall x. Rep Offset x -> Offset
to :: forall x. Rep Offset x -> Offset
Generic)
  deriving newtype (Offset -> Offset -> Bool
(Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool) -> Eq Offset
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Offset -> Offset -> Bool
== :: Offset -> Offset -> Bool
$c/= :: Offset -> Offset -> Bool
/= :: Offset -> Offset -> Bool
Eq, Eq Offset
Eq Offset =>
(Offset -> Offset -> Ordering)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Bool)
-> (Offset -> Offset -> Offset)
-> (Offset -> Offset -> Offset)
-> Ord Offset
Offset -> Offset -> Bool
Offset -> Offset -> Ordering
Offset -> Offset -> Offset
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 :: Offset -> Offset -> Ordering
compare :: Offset -> Offset -> Ordering
$c< :: Offset -> Offset -> Bool
< :: Offset -> Offset -> Bool
$c<= :: Offset -> Offset -> Bool
<= :: Offset -> Offset -> Bool
$c> :: Offset -> Offset -> Bool
> :: Offset -> Offset -> Bool
$c>= :: Offset -> Offset -> Bool
>= :: Offset -> Offset -> Bool
$cmax :: Offset -> Offset -> Offset
max :: Offset -> Offset -> Offset
$cmin :: Offset -> Offset -> Offset
min :: Offset -> Offset -> Offset
Ord, Int -> Offset -> ShowS
[Offset] -> ShowS
Offset -> String
(Int -> Offset -> ShowS)
-> (Offset -> String) -> ([Offset] -> ShowS) -> Show Offset
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Offset -> ShowS
showsPrec :: Int -> Offset -> ShowS
$cshow :: Offset -> String
show :: Offset -> String
$cshowList :: [Offset] -> ShowS
showList :: [Offset] -> ShowS
Show, Offset -> ()
(Offset -> ()) -> NFData Offset
forall a. (a -> ()) -> NFData a
$crnf :: Offset -> ()
rnf :: Offset -> ()
NFData)

-- | The offset of a node that does not come from an input.
noOffset :: Offset
noOffset :: Offset
noOffset = Int -> Offset
Offset (-Int
1)

-- | Copy every text of a document, so that the document does not keep the
-- input alive.
copyDocument :: Document -> Document
copyDocument :: Document -> Document
copyDocument Document
doc =
  Document
doc
    { docComments = copyComments doc.docComments
    , root = copyNode doc.root
    }

-- | Copy every text of a node, so that the node does not keep the input
-- alive.
copyNode :: Node -> Node
copyNode :: Node -> Node
copyNode Node
n =
  Node
n
    { props = case n.props of
        -- Most nodes share one empty value, which a copy would duplicate.
        Props Maybe Text
Nothing (Tag Text
t) -> Maybe Text -> Tag -> Props
Props Maybe Text
forall a. Maybe a
Nothing (Text -> Tag
Tag (Text -> Text
T.copy Text
t))
        Props Maybe Text
Nothing Tag
_ -> Node
n.props
        Props Maybe Text
anchor Tag
tag ->
          Props
            { anchor :: Maybe Text
anchor = Maybe Text -> Maybe Text
copyMaybe Maybe Text
anchor
            , tag :: Tag
tag = case Tag
tag of
                Tag Text
t -> Text -> Tag
Tag (Text -> Text
T.copy Text
t)
                Tag
t -> Tag
t
            }
    , comments = case n.comments of
        -- Most nodes share one empty value. GHC returns the result of
        -- 'copyComments' unboxed, so the caller would build a new one.
        c :: Comments
c@(Comments [] Maybe Text
Nothing []) -> Comments
c
        Comments
c -> Comments -> Comments
copyComments Comments
c
    , content = case n.content of
        ScalarLinesContent ScalarStyle
style Text
t [Int]
ls -> ScalarStyle -> Text -> [Int] -> Content
ScalarLinesContent ScalarStyle
style (Text -> Text
T.copy Text
t) [Int]
ls
        SequenceContent CollectionStyle
style [Node]
xs -> CollectionStyle -> [Node] -> Content
SequenceContent CollectionStyle
style ((Node -> Node) -> [Node] -> [Node]
forall a b. (a -> b) -> [a] -> [b]
strictMap Node -> Node
copyNode [Node]
xs)
        MappingContent CollectionStyle
style [(Node, Node)]
kvs ->
          CollectionStyle -> [(Node, Node)] -> Content
MappingContent
            CollectionStyle
style
            (((Node, Node) -> (Node, Node)) -> [(Node, Node)] -> [(Node, Node)]
forall a b. (a -> b) -> [a] -> [b]
strictMap (\(Node
k, Node
v) -> Node -> Node -> (Node, Node)
forall a b. a -> b -> (a, b)
strictPair (Node -> Node
copyNode Node
k) (Node -> Node
copyNode Node
v)) [(Node, Node)]
kvs)
        AliasContent Text
name -> Text -> Content
AliasContent (Text -> Text
T.copy Text
name)
    }

copyComments :: Comments -> Comments
copyComments :: Comments -> Comments
copyComments Comments
c = case Comments
c of
  Comments [] Maybe Text
Nothing [] -> Comments
c
  Comments
_ ->
    Comments
      { before :: [Line]
before = (Line -> Line) -> [Line] -> [Line]
forall a b. (a -> b) -> [a] -> [b]
strictMap Line -> Line
copyLine Comments
c.before
      , inline :: Maybe Text
inline = Maybe Text -> Maybe Text
copyMaybe Comments
c.inline
      , after :: [Line]
after = (Line -> Line) -> [Line] -> [Line]
forall a b. (a -> b) -> [a] -> [b]
strictMap Line -> Line
copyLine Comments
c.after
      }
  where
    copyLine :: Line -> Line
    copyLine :: Line -> Line
copyLine = \case
      CommentLine Int
n Text
t -> Int -> Text -> Line
CommentLine Int
n (Text -> Text
T.copy Text
t)
      Line
EmptyLine -> Line
EmptyLine

-- | A copy without a thunk, which would keep the original text alive.
copyMaybe :: Maybe T.Text -> Maybe T.Text
copyMaybe :: Maybe Text -> Maybe Text
copyMaybe = \case
  Just Text
t -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$! Text -> Text
T.copy Text
t
  Maybe Text
Nothing -> Maybe Text
forall a. Maybe a
Nothing

-- $setup
-- >>> import Data.Map.Strict qualified as M
-- >>> import Data.Text.IO qualified as T
-- >>> import Yamlet
-- >>> import Yamlet.Syntax
-- >>> printErrors = mapM_ (putStrLn . prettyError "input.yaml")