yamlet
Safe HaskellNone
LanguageGHC2021

Yamlet

Description

A YAML 1.2.2 library.

The library handles two typical use cases well:

  1. Decoding a document that describes a configuration:

    >>> :{
    data Config = Config
      { name :: T.Text
      , paths :: [FilePath]
      }
      deriving stock (Generic, Show)
      deriving (FromYaml) via GenericYaml Config
    instance GenericYamlOptions Config where
      yamlDefault = Just Config {name = requiredField, paths = ["."]}
    :}
    
    >>> input = "name: app\n"
    
    >>> T.putStr input
    name: app
    
    >>> either printErrors print (decodeText @Config input)
    Config {name = "app", paths = ["."]}
    

    When a document fails to decode, you get multiple errors pointing at what failed and why:

    >>> input = "paths:\n- src\n- 42\nport: 80\n"
    
    >>> T.putStr input
    paths:
    - src
    - 42
    port: 80
    
    >>> either printErrors print (decodeText @Config input)
    input.yaml:1:1: missing key "name"
      |
    1 | paths:
      | ^
    input.yaml:3:3: paths[1]: expected a string, but got an integer, quote the value, e.g. '42'
      |
    3 | - 42
      |   ^
    input.yaml:4:1: unknown key "port", expected one of: name, paths
      |
    4 | port: 80
      | ^
    
  2. Decoding a document into a Haskell type and encoding it back. A type can keep the comments of a value with Commented, and a part of the document as it was written with Node:

    >>> :{
    data Workflow = Workflow
      { name :: Commented T.Text
      , matrix :: Node
      }
      deriving stock (Generic)
      deriving anyclass (GenericYamlOptions)
      deriving (FromYaml, ToYaml) via GenericYaml Workflow
    :}
    
    >>> input = "# The name in the UI.\nname: build # short\nmatrix:\n  # Each system runs the jobs.\n  os: [linux, macos]\n  ghc: ['9.10', '9.12']\n"
    
    >>> T.putStr input
    # The name in the UI.
    name: build # short
    matrix:
      # Each system runs the jobs.
      os: [linux, macos]
      ghc: ['9.10', '9.12']
    
    >>> Right workflow = decodeText @Workflow input
    

    The decoded name keeps the comment above its key and the comment after its value:

    >>> print workflow.name
    Commented {value = "build", comments = Comments {before = [Comment "The name in the UI."], inline = Just "short", after = []}}
    
    >>> T.putStr (encodeText workflow)
    # The name in the UI.
    name: build # short
    matrix:
      # Each system runs the jobs.
      os: [linux, macos]
      ghc: ['9.10', '9.12']
    

The record types of the library, e.g. Error and YamlOptions, have no field selectors. Read a field with the OverloadedRecordDot extension, e.g. err.message, and set one with the record syntax, e.g. defaultYamlOptions {fieldLabelModifier = snakeCase}, or with the generic optics of optics-core, e.g. defaultYamlOptions & #fieldLabelModifier .~ snakeCase.

Synopsis

Decoding

decode :: FromYaml a => ByteString -> Either (NonEmpty Error) a Source #

Decode a stream with one document. An empty stream is null.

If the input has a syntax error or fails a check that decodeDocument describes, the result has only that error, with its notes, e.g. the first key of a duplicate key. Otherwise the result has every error that the Parser collects, in the order of their positions.

>>> decode @[Int] "- 1\n- 2\n"
Right [1,2]
>>> decode @(Maybe Int) ""
Right Nothing
>>> either printErrors print (decode @[Int] "- 1\n- x\n- true\n")
input.yaml:2:3: [1]: expected an integer, but got a string
  |
2 | - x
  |   ^
input.yaml:3:3: [2]: expected an integer, but got a boolean
  |
3 | - true
  |   ^

decodeAll :: FromYaml a => ByteString -> Either (NonEmpty Error) [a] Source #

Decode every document of a stream. The errors are as for decode, from the first document that fails. The parser reads the whole stream first, so a syntax error in any document comes before the errors of the others.

>>> decodeAll @Int "1\n---\n2\n"
Right [1,2]

decodeText :: FromYaml a => Text -> Either (NonEmpty Error) a Source #

Decode a stream with one document. An empty stream is null. The errors are as for decode.

>>> decodeText @Value "ports: [80, 443]\nenabled: yes\n"
Right (Mapping [(String "ports",Sequence [Int 80,Int 443]),(String "enabled",String "yes")])

decodeAllText :: FromYaml a => Text -> Either (NonEmpty Error) [a] Source #

Decode every document of a stream. The errors are as for decodeAll.

decodeInput :: ByteString -> Either Error Text Source #

Decode the bytes of a stream to text. The encoding is UTF-8, UTF-16 or UTF-32, detected as the YAML specification describes.

decodeFile :: FromYaml a => FilePath -> IO (Either (NonEmpty Error) a) Source #

Decode the file as decode does. The file is read as bytes, so the encoding does not depend on the locale. It is UTF-8, UTF-16 or UTF-32, detected as the YAML specification describes.

For the errors, give the same path to prettyError:

decodeFile @Config path >>= \case
  Left errs -> mapM_ (putStrLn . prettyError path) errs
  Right config -> ...

decodeAllFile :: FromYaml a => FilePath -> IO (Either (NonEmpty Error) [a]) Source #

Decode every document of the file as decodeAll does, with the encoding of decodeFile.

Syntax trees

decodeWithDocument :: FromYaml a => Text -> Either (NonEmpty Error) (a, Document) Source #

Decode a stream with one document as decodeText does, and give the document too, e.g. for documentErrors or to write the file back with its comments. An empty stream is a document with null. A stream of only comments is empty too, so the document does not keep them, as the section Comments says.

decodeDocument :: FromYaml a => Text -> Document -> Either (NonEmpty Error) a Source #

Decode a document of a syntax tree, e.g. to read the values of a file and keep its comments from one parse.

As for a parsed input, the decoder checks the document first. The check fails for:

  • a duplicate key,
  • an undefined alias,
  • an alias inside the node that it refers to, e.g. &a [*a],
  • aliases beyond the limit in Yamlet.Value,
  • a value that is not valid for its tag,
  • a float whose exponent in scientific notation is beyond the range from -1000 to 1000.

The text is the input of the document. An error takes its line from the text. For a document that the program built, the text can be empty. If such a document contains the nodes of a parsed input, pass that input, so that their errors get their lines. The errors are as for decode.

The document has the limit of the aliases to itself. For the documents of a stream, use decodeDocuments, so that they share the limit.

decodeDocuments :: FromYaml a => Text -> [Document] -> Either (NonEmpty Error) [a] Source #

Decode the documents of a syntax tree as decodeDocument does, e.g. the documents of a stream from parseDocumentsText. The documents share the limit of the aliases, as the documents of a stream do. The errors are as for decodeAll.

Encoding

encode :: ToYaml a => a -> ByteString Source #

Encode a value as a document.

>>> encode [1, 2 :: Int]
"- 1\n- 2\n"

encodeAll :: ToYaml a => [a] -> ByteString Source #

Encode values as a stream of documents.

encodeText :: ToYaml a => a -> Text Source #

Encode a value as a document.

>>> T.putStr (encodeText (mapping ["name" .= ("app" :: T.Text), "ports" .= [80, 443 :: Int]]))
name: app
ports:
- 80
- 443

encodeAllText :: ToYaml a => [a] -> Text Source #

Encode values as a stream of documents.

>>> T.putStr (encodeAllText [1, 2 :: Int])
1
---
2

encodeFile :: ToYaml a => FilePath -> a -> IO () Source #

Encode a value as a document in the file, in UTF-8. The file is written as bytes, so the encoding does not depend on the locale.

encodeAllFile :: ToYaml a => FilePath -> [a] -> IO () Source #

Encode values as a stream of documents in the file, as encodeFile does.

Nodes

data Node Source #

A node of a document.

Instances

Instances details
NFData Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Node -> ()

Generic Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Node 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Node = D1 ('MetaData "Node" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Node" 'PrefixI 'True) ((S1 ('MetaSel ('Just "offset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset) :*: S1 ('MetaSel ('Just "endOffset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset)) :*: (S1 ('MetaSel ('Just "props") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Props) :*: (S1 ('MetaSel ('Just "comments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments) :*: S1 ('MetaSel ('Just "content") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Content)))))

Methods

from :: Node -> Rep Node x

to :: Rep Node x -> Node

Show Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Node -> ShowS

show :: Node -> String

showList :: [Node] -> ShowS

Eq Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Node -> Node -> Bool

(/=) :: Node -> Node -> Bool

FromYaml Node Source #

The node of the syntax tree, with its styles and comments, e.g. to write a part of a document back as it was written. An alias in the input gives a copy of the node that it refers to.

The texts of the node are copies, so that a small part of a document does not keep the whole input alive. For a whole document without a copy, use parseDocuments.

Instance details

Defined in Yamlet.Internal.FromYaml

ToYaml Node Source # 
Instance details

Defined in Yamlet.Internal.ToYaml

type Rep Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Node = D1 ('MetaData "Node" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Node" 'PrefixI 'True) ((S1 ('MetaSel ('Just "offset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset) :*: S1 ('MetaSel ('Just "endOffset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset)) :*: (S1 ('MetaSel ('Just "props") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Props) :*: (S1 ('MetaSel ('Just "comments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments) :*: S1 ('MetaSel ('Just "content") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Content)))))

newtype Offset Source #

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 decodeInput, not the bytes of the input.

Constructors

Offset Int 

Instances

Instances details
NFData Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Offset -> ()

Generic Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Offset 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Offset = D1 ('MetaData "Offset" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'True) (C1 ('MetaCons "Offset" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

Methods

from :: Offset -> Rep Offset x

to :: Rep Offset x -> Offset

Show Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Offset -> ShowS

show :: Offset -> String

showList :: [Offset] -> ShowS

Eq Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Offset -> Offset -> Bool

(/=) :: Offset -> Offset -> Bool

Ord Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

compare :: Offset -> Offset -> Ordering

(<) :: Offset -> Offset -> Bool

(<=) :: Offset -> Offset -> Bool

(>) :: Offset -> Offset -> Bool

(>=) :: Offset -> Offset -> Bool

max :: Offset -> Offset -> Offset

min :: Offset -> Offset -> Offset

type Rep Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Offset = D1 ('MetaData "Offset" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'True) (C1 ('MetaCons "Offset" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

noOffset :: Offset Source #

The offset of a node that does not come from an input.

data Located a Source #

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.

documentErrors turns the offsets into errors with lines, columns and paths. It needs the text and the document of the decode, so decode with 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 yamlDefault, has noOffset. Its error has no position, and 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 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.

Constructors

Located 

Fields

Instances

Instances details
Functor Located Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

fmap :: (a -> b) -> Located a -> Located b

(<$) :: a -> Located b -> Located a

Foldable Located Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

fold :: Monoid m => Located m -> m

foldMap :: Monoid m => (a -> m) -> Located a -> m

foldMap' :: Monoid m => (a -> m) -> Located a -> m

foldr :: (a -> b -> b) -> b -> Located a -> b

foldr' :: (a -> b -> b) -> b -> Located a -> b

foldl :: (b -> a -> b) -> b -> Located a -> b

foldl' :: (b -> a -> b) -> b -> Located a -> b

foldr1 :: (a -> a -> a) -> Located a -> a

foldl1 :: (a -> a -> a) -> Located a -> a

toList :: Located a -> [a]

null :: Located a -> Bool

length :: Located a -> Int

elem :: Eq a => a -> Located a -> Bool

maximum :: Ord a => Located a -> a

minimum :: Ord a => Located a -> a

sum :: Num a => Located a -> a

product :: Num a => Located a -> a

Traversable Located Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

traverse :: Applicative f => (a -> f b) -> Located a -> f (Located b)

sequenceA :: Applicative f => Located (f a) -> f (Located a)

mapM :: Monad m => (a -> m b) -> Located a -> m (Located b)

sequence :: Monad m => Located (m a) -> m (Located a)

NFData a => NFData (Located a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Located a -> ()

Generic (Located a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep (Located a) 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep (Located a) = D1 ('MetaData "Located" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Located" 'PrefixI 'True) (S1 ('MetaSel ('Just "value") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 a) :*: S1 ('MetaSel ('Just "offset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset)))

Methods

from :: Located a -> Rep (Located a) x

to :: Rep (Located a) x -> Located a

Show a => Show (Located a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Located a -> ShowS

show :: Located a -> String

showList :: [Located a] -> ShowS

Eq a => Eq (Located a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Located a -> Located a -> Bool

(/=) :: Located a -> Located a -> Bool

Ord a => Ord (Located a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

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

max :: Located a -> Located a -> Located a

min :: Located a -> Located a -> Located a

FromYaml a => FromYaml (Located a) Source #

The value with the offset of its node. The key of an entry goes to the value inside, e.g. for a Commented value.

Instance details

Defined in Yamlet.Internal.FromYaml

ToYaml a => ToYaml (Located a) Source #

The value alone. The key of an entry goes to the value inside, e.g. for a Commented value.

Instance details

Defined in Yamlet.Internal.ToYaml

type Rep (Located a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep (Located a) = D1 ('MetaData "Located" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Located" 'PrefixI 'True) (S1 ('MetaSel ('Just "value") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 a) :*: S1 ('MetaSel ('Just "offset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset)))

Comments

data Commented a Source #

A value with the comments of its mapping entry:

  • before: the lines above the entry,
  • inline: the comment at the end of the line of the key, or of the line where a value on several lines ends,
  • after: the lines after the value, e.g. after the last entry of a collection.

A 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 Commented value inside the first one keeps them, so a type that keeps both nests two 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.

  # 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 Commented value of the whole list or mapping keeps them.

By the rules in 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 Commented list or mapping keeps them. Under a key, the inner of two nested 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 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 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 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.

Constructors

Commented 

Fields

Instances

Instances details
Functor Commented Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

fmap :: (a -> b) -> Commented a -> Commented b

(<$) :: a -> Commented b -> Commented a

Foldable Commented Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

fold :: Monoid m => Commented m -> m

foldMap :: Monoid m => (a -> m) -> Commented a -> m

foldMap' :: Monoid m => (a -> m) -> Commented a -> m

foldr :: (a -> b -> b) -> b -> Commented a -> b

foldr' :: (a -> b -> b) -> b -> Commented a -> b

foldl :: (b -> a -> b) -> b -> Commented a -> b

foldl' :: (b -> a -> b) -> b -> Commented a -> b

foldr1 :: (a -> a -> a) -> Commented a -> a

foldl1 :: (a -> a -> a) -> Commented a -> a

toList :: Commented a -> [a]

null :: Commented a -> Bool

length :: Commented a -> Int

elem :: Eq a => a -> Commented a -> Bool

maximum :: Ord a => Commented a -> a

minimum :: Ord a => Commented a -> a

sum :: Num a => Commented a -> a

product :: Num a => Commented a -> a

Traversable Commented Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

traverse :: Applicative f => (a -> f b) -> Commented a -> f (Commented b)

sequenceA :: Applicative f => Commented (f a) -> f (Commented a)

mapM :: Monad m => (a -> m b) -> Commented a -> m (Commented b)

sequence :: Monad m => Commented (m a) -> m (Commented a)

NFData a => NFData (Commented a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Commented a -> ()

Generic (Commented a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep (Commented a) 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep (Commented a) = D1 ('MetaData "Commented" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Commented" 'PrefixI 'True) (S1 ('MetaSel ('Just "value") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 a) :*: S1 ('MetaSel ('Just "comments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments)))

Methods

from :: Commented a -> Rep (Commented a) x

to :: Rep (Commented a) x -> Commented a

Show a => Show (Commented a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Commented a -> ShowS

show :: Commented a -> String

showList :: [Commented a] -> ShowS

Eq a => Eq (Commented a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Commented a -> Commented a -> Bool

(/=) :: Commented a -> Commented a -> Bool

Ord a => Ord (Commented a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

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

max :: Commented a -> Commented a -> Commented a

min :: Commented a -> Commented a -> Commented a

FromYaml a => FromYaml (Commented a) Source #

The value with the comments of its entry, or of its node if it has no key, copied like every decoded text.

Instance details

Defined in Yamlet.Internal.FromYaml

ToYaml a => ToYaml (Commented a) Source #

The value with the comments of its entry. The lines above and the comment of the first line go on the key, or on the value without a key. A key keeps its own lines above, or its own comment, if the value has none. The lines after the value replace its own.

Instance details

Defined in Yamlet.Internal.ToYaml

type Rep (Commented a) Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep (Commented a) = D1 ('MetaData "Commented" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Commented" 'PrefixI 'True) (S1 ('MetaSel ('Just "value") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 a) :*: S1 ('MetaSel ('Just "comments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments)))

data Comments Source #

The comments and the empty lines that belong to a node.

Constructors

Comments 

Fields

  • before :: ![Line]

    The lines above the node.

  • inline :: !(Maybe 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.

  • 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 gives the rules. The renderer writes such lines below any node.

Instances

Instances details
NFData Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Comments -> ()

Generic Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Comments 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Comments = D1 ('MetaData "Comments" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Comments" 'PrefixI 'True) (S1 ('MetaSel ('Just "before") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]) :*: (S1 ('MetaSel ('Just "inline") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe Text)) :*: S1 ('MetaSel ('Just "after") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]))))

Methods

from :: Comments -> Rep Comments x

to :: Rep Comments x -> Comments

Show Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Comments -> ShowS

show :: Comments -> String

showList :: [Comments] -> ShowS

Eq Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Comments -> Comments -> Bool

(/=) :: Comments -> Comments -> Bool

Ord Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

compare :: Comments -> Comments -> Ordering

(<) :: Comments -> Comments -> Bool

(<=) :: Comments -> Comments -> Bool

(>) :: Comments -> Comments -> Bool

(>=) :: Comments -> Comments -> Bool

max :: Comments -> Comments -> Comments

min :: Comments -> Comments -> Comments

type Rep Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Comments = D1 ('MetaData "Comments" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Comments" 'PrefixI 'True) (S1 ('MetaSel ('Just "before") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]) :*: (S1 ('MetaSel ('Just "inline") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe Text)) :*: S1 ('MetaSel ('Just "after") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]))))

noComments :: Comments Source #

No comments and no empty lines.

data Line Source #

A line of comments.

Constructors

EmptyLine 
CommentLine !Int !Text

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 Comments is a text without a count. It keeps the # characters after the first one in its text.

Bundled Patterns

pattern Comment :: Text -> Line

A comment with one #. As a pattern, it matches every comment and ignores the number of # characters.

Instances

Instances details
NFData Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Line -> ()

Generic Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Line 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Line = D1 ('MetaData "Line" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "EmptyLine" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "CommentLine" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text)))

Methods

from :: Line -> Rep Line x

to :: Rep Line x -> Line

Show Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Line -> ShowS

show :: Line -> String

showList :: [Line] -> ShowS

Eq Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Line -> Line -> Bool

(/=) :: Line -> Line -> Bool

Ord Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

compare :: Line -> Line -> Ordering

(<) :: Line -> Line -> Bool

(<=) :: Line -> Line -> Bool

(>) :: Line -> Line -> Bool

(>=) :: Line -> Line -> Bool

max :: Line -> Line -> Line

min :: Line -> Line -> Line

type Rep Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Line = D1 ('MetaData "Line" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "EmptyLine" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "CommentLine" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text)))

Values

Conversion from nodes

Conversion to nodes

Generic instances

Errors