Added setTagUriForType. Used it. Improved docs.

This commit is contained in:
Felix Krause 2016-02-15 19:46:21 +01:00
parent 8d472d3278
commit 02e505959a
8 changed files with 141 additions and 342 deletions

209
README.md
View File

@ -1,213 +1,11 @@
# NimYAML - YAML implementation for Nim
NimYAML is a YAML implementation in Nim. It aims to implement the complete
YAML 1.2 specification and has a streaming interface that makes it possible to
parse YAML input sequentially, without loading all data into memory at once. It
is able to automatically serialize Nim object to YAML and deserialize them
again.
**Attention**: NimYAML is work in progress. There is no release yet, and some
features are highly experimental.
## Quickstart
### Using the sequential parser
```Nimrod
import yaml
let input = """
an integer: 42
a boolean: yes
a list:
- 3.14159
- !!str 23
- null
"""
var
parser = newYamlParser(initCoreTagLibrary())
events = parser.parse(newStringStream(input))
for event in events():
echo $event
```
Output:
```
yamlStartDocument()
yamlStartMap(tag=?)
yamlScalar(tag=?, typeHint=yTypeUnknown, content="an integer")
yamlScalar(tag=?, typeHint=yTypeInteger, content="42")
yamlScalar(tag=?, typeHint=yTypeUnknown, content="a boolean")
yamlScalar(tag=?, typeHint=yTypeBoolTrue, content="yes")
yamlScalar(tag=?, typeHint=yTypeUnknown, content="a list")
yamlStartSequence(tag=?)
yamlScalar(tag=?, typeHint=yTypeFloat, content="3.14159")
yamlScalar(tag=!!str, typeHint=yTypeInteger, content="23")
yamlScalar(tag=?, typeHint=yTypeNull, content="null")
yamlEndSequence()
yamlEndMap()
yamlEndDocument()
```
### Dumping YAML
```Nimrod
import yaml, streams
proc example(): YamlStream =
result = iterator(): YamlStreamEvent =
yield startDocEvent()
yield startMapEvent()
yield scalarEvent("an integer")
yield scalarEvent("42", tag = yTagInteger)
yield scalarEvent("a list")
yield startSeqEvent(tag = yTagSequence)
yield scalarEvent("item", tag = yTagString)
yield scalarEvent("no", tag = yTagBoolean)
yield scalarEvent("")
yield endSeqEvent()
yield scalarEvent("a float")
yield scalarEvent("3.14159", tag = yTagFloat)
yield endMapEvent()
yield endDocEvent()
present(example(), newFileStream(stdout), initCoreTagLibrary(), psBlockOnly)
echo "\n\n"
present(example(), newFileStream(stdout), initCoreTagLibrary(), psCanonical)
echo "\n\n"
present(example(), newFileStream(stdout), initCoreTagLibrary(), psJson)
```
Output:
```
%YAML 1.2
---
an integer: !!int 42
a list: !!seq
- !!str item
- !!bool no
- ""
a float: !!float 3.14159
%YAML 1.2
---
{
? "an integer"
: !!int "42",
? "a list"
: !!seq [
!!str "item",
!!bool "no",
""
],
? "a float"
: !!float "3.14159"
}
{
"an integer": 42,
"a list": [
"item",
false,
""
],
"a float": 3.14159
}
```
### Using Nim Type Serialization
**Attention**: This feature is highly experimental!
```Nimrod
import yaml.serialization
import tables
serializable:
type
Person = object
firstname, surname: string
age: int32
additionalAttributes: Table[string, string]
# loading
let input = """
-
firstname: Peter
surname: Pan
age: 12
additionalAttributes:
canFly: yes
location: Neverland
-
firstname: Karl
surname: Koch
age: 23
additionalAttributes:
location: Celle
occupation: Hacker
"""
var persons: seq[Person]
load(newStringStream(input), persons)
assert persons[0].surname == "Pan"
assert persons[1].additionalAttributes["location"] == "Celle"
# dumping
dump(persons, newFileStream(stdout), psCanonical)
```
Output:
```
%YAML 1.2
--- !nim:seq(nim:Person)
[
!nim:Person {
? !!str "firstname"
: !!str "Peter",
? !!str "surname"
: !!str "Pan",
? !!str "age"
: !nim:int "12",
? !!str "additionalAttributes"
: !nim:Table(tag:yaml.org,2002:str,tag:yaml.org,2002:str) {
? !!str "canFly"
: !!str "yes",
? !!str "location"
: !!str "Neverland"
}
},
!nim:Person {
? !!str "firstname"
: !!str "Karl",
? !!str "surname"
: !!str "Koch",
? !!str "age"
: !nim:int "23",
? !!str "additionalAttributes"
: !nim:Table(tag:yaml.org,2002:str,tag:yaml.org,2002:str) {
? !!str "occupation"
: !!str "Hacker",
? !!str "location"
: !!str "Celle"
}
}
]
```
NimYAML is currently being developed. There is no release yet. See
[the documentation](http://flyx.github.io/NimYAML/) for an overview of already
available features.
## TODO list
* Documentation:
- Document yaml.serialization
* Misc:
- Add type hints for more scalar types
* Serialization:
@ -216,7 +14,6 @@ Output:
- Support variant objects
- Support transient fields (i.e. fields that will not be (de-)serialized on
objects and tuples)
- Make it possible for user to define a tag URI for custom types
- Use `concept` type class `Serializable` or something
- Check for and avoid name clashes when generating local tags for custom
object types.

View File

@ -22,6 +22,7 @@ task documentation, "Generate documentation":
exec "mkdir -p docout"
exec r"nim doc2 -o:docout/yaml.html --docSeeSrcUrl:https://github.com/flyx/NimYAML/blob/`git log -n 1 --format=%H` yaml"
exec r"nim rst2html -o:docout/index.html doc/index.txt"
exec r"nim rst2html -o:docout/api.html doc/api.txt"
exec "cp doc/docutils.css doc/style.css doc/testing.html doc/processing.svg docout"
setCommand "nop"

86
doc/api.txt Normal file
View File

@ -0,0 +1,86 @@
===
API
===
Overview
========
NimYAML advocates parsing YAML input into native Nim types. Basic Nim library
types like integers, floats and strings, as well as all tuples, enums and
objects without private fields are supported out-of-the-box. Reference types are
also supported, and NimYAML is able to detect if a reference occurs more than
once and will serialize it accordingly. This means that NimYAML is able to dump
and load potentially cyclic objects.
While loading into and dumping from native Nim types is the preferred way to use
NimYAML, it also gives you complete control over each processing step, so that
you can for example only use the parser and process its event stream yourself.
The following diagram gives an overview of NimYAML's features based on the YAML
processing pipeline. The items and terminology YAML defines is shown in
*italic*, NimYAML's implementation name is shown in **bold**.
.. image:: processing.svg
Intermediate Representation
===========================
The base of all YAML processing with NimYAML is the
`YamlStream <yaml.html#YamlStream>`_. This is basically an iterator over
`YamlStreamEvent <yaml.html#YamlStreamEvent>`_ objects. Every proc that
represents a single stage of the loading or dumping process will either take a
``YamlStream`` as input or return a ``YamlStream``. Procs that implement the
whole process in one step hide the ``YamlStream`` from the user. Every proc that
returns a ``YamlStream`` guarantees that this stream is well-formed according to
the YAML specification.
This stream-oriented API can efficiently be used to parse large amounts of data.
The drawback is that errors in the input are only discovered while processing
the ``YamlStream``. If the ``YamlStream`` encounters an exception while
producing the next event, it will throw a ``YamlStreamError`` which contains the
original exception as ``parent``. The caller should know which exceptions are
possible as parents of ``YamlStream`` because they know the source of the
``YamlStream`` they provided.
Loading YAML
============
If you want to load YAML character data directly into a native Nim variable, you
can use `load <yaml.html#load,Stream,K>`_. This is the easiest and recommended
way to load YAML data. The following paragraphs will explain the steps involved.
For parsing, a `YamlParser <yaml.html#YamlParser>`_ object is needed. This
object stores some state while parsing that may be useful for error reporting to
the user. The
`parse <yaml.html#present,YamlStream,Stream,TagLibrary,PresentationStyle,int>`_
proc implements the YAML processing step of the same name. All syntax errors in
the input character stream are processed by ``parse``, which will raise a
``YamlParserError`` if it encounters a syntax error.
Transforming a ``YamlStream`` to a native YAML object is done via
``construct``. It skips the ``compose`` step for efficiency reasons. As Nim is
statically typed, you have to know the target type when you write your loading
code. This is different from YAML APIs of dynamically typed languages. If you
cannot know the type of your YAML input at compile time, you have to manually
process the ``YamlStream`` to serve your needs.
Dumping YAML
============
Dumping is preferredly done with
`dump <yaml.html#dump,K,Stream,PresentationStyle,TagStyle,AnchorStyle,int>`_,
which serializes a native Nim variable to a character stream. Like ``load``, you
can use the steps involved separately.
You transform a variable into a ``YamlStream`` with
`represent <yaml.html#represent,T,TagStyle,AnchorStyle>`_. Depending on the
``AnchorStyle`` you specify, this will transform ``ref`` variables with multiple
instances into anchored elements and aliases (for ``asTidy`` and ``asAlways``)
or write the same element into all places it occurs (for ``asNone``). Be aware
that if you use ``asNone``, the value you serialize might not round-trip.
Transforming a ``YamlStream`` into YAML character data is done with
`present <yaml.html#present,YamlStream,Stream,TagLibrary,PresentationStyle,int>`_.
You can choose from multiple presentation styles. ``psJson`` is not able to
process some features of ``YamlStream``s, the other styles support all features
and are guaranteed to round-trip to the same ``YamlStream`` if you parse the
generated YAML character stream again.

View File

@ -70,78 +70,3 @@ NimYAML's features.
of other: echo "child: ", child.name
echo "------------------------"
dump(persons, newFileStream(stdout))
API Overview
============
NimYAML advocates parsing YAML input into native Nim types. Basic library types
like integers, floats and strings, as well as all tuples, enums and objects
without private fields are supported out-of-the-box. Reference types are also
supported, and NimYAML is able to detect if a reference occurs more than once
and will serialize it accordingly. This means that NimYAML is able to dump and
load potentially cyclic objects.
While loading into and dumping from native Nim types is the preferred way to use
NimYAML, it also gives you complete control over each processing step, so that
you can for example only use the parser and process its event stream yourself.
The following diagram gives an overview of NimYAML's features based on the YAML
processing pipeline. The items and terminology YAML defines is shown in
*italic*, NimYAML's implementation name is shown in **bold**.
.. image:: processing.svg
Intermediate Representation
---------------------------
The base of all YAML processing with NimYAML is the
`YamlStream <yaml.html#YamlStream>`_. This is basically an iterator over
`YamlStreamEvent <yaml.html#YamlStreamEvent>`_ objects. Every proc that
represents a single stage of the loading or dumping process will either take a
``YamlStream`` as input or return a ``YamlStream``. Procs that implement the
whole process in one step hide the ``YamlStream`` from the user. Every proc that
returns a ``YamlStream`` guarantees that this stream is well-formed according to
the YAML specification.
This stream-oriented API can efficiently be used to parse large amounts of data.
The drawback is that errors in the input are only discovered while processing
the ``YamlStream``. If the ``YamlStream`` encounters an exception while
producing the next event, it will throw a ``YamlStreamError`` which contains the
original exception as ``parent``. The caller should know which exceptions are
possible as parents of ``YamlStream`` because they know the source of the
``YamlStream`` they provided.
Loading YAML
------------
For parsing, a `YamlParser <yaml.html#YamlParser>`_ object is needed. This
object stores some state while parsing that may be useful for error reporting to
the user. The
`parse <yaml.html#present,YamlStream,Stream,TagLibrary,PresentationStyle,int>`_
proc implements the YAML processing step of the same name. All syntax errors in
the input character stream are processed by ``parse``, which will raise a
``YamlParserError`` if it encounters a syntax error.
Transforming a ``YamlStream`` to a native YAML object is done via
``construct``. It skips the ``compose`` step for efficiency reasons. As Nim is
statically typed, you have to know the target type when you write your loading
code. This is different from YAML APIs of dynamically typed languages. If you
cannot know the type of your YAML input at compile time, you have to manually
process the ``YamlStream`` to serve your needs.
If you want to load YAML character data directly into a native Nim variable, you
can use `load <yaml.html#load,Stream,K>`_.
Dumping YAML
------------
Dumping YAML is straightforward: You transform a variable into a ``YamlStream``
with `represent <yaml.html#represent,T,TagStyle,AnchorStyle>`_ and then write
that to a stream using
`present <yaml.html#present,YamlStream,Stream,TagLibrary,PresentationStyle,int>`_.
If you want to execute both steps at once, you can use
`dump <yaml.html#dump,K,Stream,PresentationStyle,TagStyle,AnchorStyle,int>`_.
The ``present`` step allows you to specify how you want the output YAML
character stream to be formatted. Amongst other options, it is possible to
output pure JSON, but only if the stream does not contain any constructs that
cannot be presented in JSON.

View File

@ -96,9 +96,7 @@
<g id="atomics" text-anchor="middle" transform="translate(0 90)">
<g id="represent" transform="translate(65 10)">
<use xlink:href="#atomic-right-long"/>
<a xlink:href="yaml.html#represent,T,TagStyle,AnchorStyle" target="_top">
<text x="80" y="25" font-style="italic">represent</text>
</a>
<text x="80" y="25" font-style="italic">represent</text>
</g>
<g id="serialize" transform="translate(235 10)">
@ -115,9 +113,7 @@
<g id="construct" transform="translate(65 120)">
<use xlink:href="#atomic-left-long"/>
<a xlink:href="yaml.html#construct,YamlStream,T" target="_top">
<text x="80" y="35" font-style="italic">construct</text>
</a>
<text x="80" y="35" font-style="italic">construct</text>
</g>
<g id="compose" transform="translate(235 120)">

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -23,17 +23,6 @@ proc initSerializationTagLibrary(): TagLibrary {.raises: [].} =
result.tags["tag:yaml.org,2002:timestamp"] = yTagTimestamp
result.tags["tag:yaml.org,2002:value"] = yTagValue
result.tags["tag:yaml.org,2002:binary"] = yTagBinary
result.tags["!nim:system:int8"] = yTagNimInt8
result.tags["!nim:system:int16"] = yTagNimInt16
result.tags["!nim:system:int32"] = yTagNimInt32
result.tags["!nim:system:int64"] = yTagNimInt64
result.tags["!nim:system:uint8"] = yTagNimUInt8
result.tags["!nim:system:uint16"] = yTagNimUInt16
result.tags["!nim:system:uint32"] = yTagNimUInt32
result.tags["!nim:system:uint64"] = yTagNimUInt64
result.tags["!nim:system:float32"] = yTagNimFloat32
result.tags["!nim:system:float64"] = yTagNimFloat64
result.tags["!nim:system:char"] = yTagNimChar
var
serializationTagLibrary* = initSerializationTagLibrary() ## \
@ -44,7 +33,6 @@ var
## Should not be modified manually. Will be extended by
## `serializable <#serializable,stmt,stmt>`_.
static:
iterator objectFields(n: NimNode): tuple[name: NimNode, t: NimNode]
{.raises: [].} =
@ -59,6 +47,31 @@ static:
template presentTag(t: typedesc, ts: TagStyle): TagId =
if ts == tsNone: yTagQuestionMark else: yamlTag(t)
template setTagUriForType*(t: typedesc, uri: string): stmt =
## Associate the given uri with a certain type. This uri is used as YAML tag
## when loading and dumping values of this type.
let id {.gensym.} = serializationTagLibrary.registerUri(uri)
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = id
template setTagUriForType*(t: typedesc, uri: string, idName: expr): stmt =
## Like `setTagUriForType <#setTagUriForType,typedesc,string>`_, but lets
## you choose a symbol for the `TagId <#TagId>`_ of the uri. This is only
## necessary if you want to implement serialization / construction yourself.
let idName* = serializationTagLibrary.registerUri(uri)
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = idName
setTagUriForType(char, "!nim:system:char", yTagNimChar)
setTagUriForType(int8, "!nim:system:int8", yTagNimInt8)
setTagUriForType(int16, "!nim:system:int16", yTagNimInt16)
setTagUriForType(int32, "!nim:system:int32", yTagNimInt32)
setTagUriForType(int64, "!nim:system:int64", yTagNimInt64)
setTagUriForType(uint8, "!nim:system:uint8", yTagNimUInt8)
setTagUriForType(uint16, "!nim:system:uint16", yTagNimUInt16)
setTagUriForType(uint32, "!nim:system:uint32", yTagNimUInt32)
setTagUriForType(uint64, "!nim:system:uint64", yTagNimUInt64)
setTagUriForType(float32, "!nim:system:float32", yTagNimFloat32)
setTagUriForType(float64, "!nim:system:float64", yTagNimFloat64)
proc lazyLoadTag*(uri: string): TagId {.inline, raises: [].} =
## Internal function. Do not call explicitly.
try:
@ -275,7 +288,8 @@ template constructScalarItem(bs: var YamlStream, item: YamlStreamEvent,
e.parent = getCurrentException()
raise e
proc yamlTag*(T: typedesc[string]): TagId {.inline, raises: [].} = yTagString
proc yamlTag*(T: typedesc[string]): TagId {.inline, noSideEffect, raises: [].} =
yTagString
proc constructObject*(s: var YamlStream, c: ConstructionContext,
result: var string)
@ -289,11 +303,6 @@ proc representObject*(value: string, ts: TagStyle = tsNone,
result = iterator(): YamlStreamEvent =
yield scalarEvent(value, presentTag(string, ts), yAnchorNone)
proc yamlTag*(T: typedesc[int8]): TagId {.inline, raises: [].} = yTagNimInt8
proc yamlTag*(T: typedesc[int16]): TagId {.inline, raises: [].} = yTagNimInt16
proc yamlTag*(T: typedesc[int32]): TagId {.inline, raises: [].} = yTagNimInt32
proc yamlTag*(T: typedesc[int64]): TagId {.inline, raises: [].} = yTagNimInt64
proc constructObject*[T: int8|int16|int32|int64](
s: var YamlStream, c: ConstructionContext, result: var T)
{.raises: [YamlConstructionError, YamlStreamError].} =
@ -317,11 +326,6 @@ template representObject*(value: int, tagStyle: TagStyle,
{.fatal: "The length of `int` is platform dependent. Use int[8|16|32|64].".}
discard
proc yamlTag*(T: typedesc[uint8]): TagId {.inline, raises: [].} = yTagNimUInt8
proc yamlTag*(T: typedesc[uint16]): TagId {.inline, raises: [].} = yTagNimUInt16
proc yamlTag*(T: typedesc[uint32]): TagId {.inline, raises: [].} = yTagNimUInt32
proc yamlTag*(T: typedesc[uint64]): TagId {.inline, raises: [].} = yTagNimUInt64
{.push overflowChecks: on.}
proc parseBiggestUInt(s: string): uint64 =
result = 0
@ -359,11 +363,6 @@ template representObject*(value: uint, ts: TagStyle, c: SerializationContext):
"The length of `uint` is platform dependent. Use uint[8|16|32|64].".}
discard
proc yamlTag*(T: typedesc[float32]): TagId {.inline, raises: [].} =
yTagNimFloat32
proc yamlTag*(T: typedesc[float64]): TagId {.inline, raises: [].} =
yTagNimFloat64
proc constructObject*[T: float32|float64](
s: var YamlStream, c: ConstructionContext, result: var T)
{.raises: [YamlConstructionError, YamlStreamError].} =
@ -431,8 +430,6 @@ proc representObject*(value: bool, ts: TagStyle,
yield scalarEvent(if value: "y" else: "n", presentTag(bool, ts),
yAnchorNone)
proc yamlTag*(T: typedesc[char]): TagId {.inline, raises: [].} = yTagNimChar
proc constructObject*(s: var YamlStream, c: ConstructionContext,
result: var char)
{.raises: [YamlConstructionError, YamlStreamError].} =
@ -617,6 +614,11 @@ proc constructObject*[O: enum](s: var YamlStream, c: ConstructionContext,
if e.kind != yamlScalar:
raise newException(YamlConstructionError, "Expected scalar, got " &
$e.kind)
if e.scalarAnchor != yAnchorNone:
raise newException(YamlConstructionError, "Anchor on a non-ref type")
if e.scalarTag notin [yTagQuestionMark, yamlTag(O)]:
raise newException(YamlConstructionError,
"Wrong tag for " & type(O).name)
try: result = parseEnum[O](e.scalarContent)
except ValueError:
var ex = newException(YamlConstructionError, "Cannot parse '" &

View File

@ -11,13 +11,17 @@ type
tlGreen, tlYellow, tlRed
Person = object
firstname, surname: string
firstnamechar: char
surname: string
age: int32
Node = object
value: string
next: ref Node
setTagUriForType(TrafficLight, "!tl")
setTagUriForType(Node, "!example.net:Node")
template assertStringEqual(expected, actual: string) =
for i in countup(0, min(expected.len, actual.len)):
if expected[i] != actual[i]:
@ -93,7 +97,7 @@ suite "Serialization":
output.data
test "Serialization: Load Enum":
let input = newStringStream("- tlRed\n- tlGreen\n- tlYellow")
let input = newStringStream("!nim:system:seq(tl)\n- !tl tlRed\n- tlGreen\n- tlYellow")
var
result: seq[TrafficLight]
parser = newYamlParser(tagLib)
@ -130,22 +134,22 @@ suite "Serialization":
output.data
test "Serialization: Load custom object":
let input = newStringStream("firstname: Peter\nsurname: Pan\nage: 12")
let input = newStringStream("firstnamechar: P\nsurname: Pan\nage: 12")
var
result: Person
parser = newYamlParser(tagLib)
events = parser.parse(input)
construct(events, result)
assert result.firstname == "Peter"
assert result.firstnamechar == 'P'
assert result.surname == "Pan"
assert result.age == 12
test "Serialization: Represent custom object":
let input = Person(firstname: "Peter", surname: "Pan", age: 12)
let input = Person(firstnamechar: 'P', surname: "Pan", age: 12)
var output = newStringStream()
dump(input, output, psBlockOnly, tsNone)
assertStringEqual(
"%YAML 1.2\n--- \nfirstname: Peter\nsurname: Pan\nage: 12",
"%YAML 1.2\n--- \nfirstnamechar: P\nsurname: Pan\nage: 12",
output.data)
test "Serialization: Load sequence with explicit tags":
@ -169,22 +173,22 @@ suite "Serialization":
test "Serialization: Load custom object with explicit root tag":
let input = newStringStream(
"--- !nim:custom:Person\nfirstname: Peter\nsurname: Pan\nage: 12")
"--- !nim:custom:Person\nfirstnamechar: P\nsurname: Pan\nage: 12")
var
result: Person
parser = newYamlParser(tagLib)
events = parser.parse(input)
construct(events, result)
assert result.firstname == "Peter"
assert result.firstnamechar == 'P'
assert result.surname == "Pan"
assert result.age == 12
test "Serialization: Represent custom object with explicit root tag":
let input = Person(firstname: "Peter", surname: "Pan", age: 12)
let input = Person(firstnamechar: 'P', surname: "Pan", age: 12)
var output = newStringStream()
dump(input, output, psBlockOnly, tsRootOnly)
assertStringEqual("%YAML 1.2\n" &
"--- !nim:custom:Person \nfirstname: Peter\nsurname: Pan\nage: 12",
"--- !nim:custom:Person \nfirstnamechar: P\nsurname: Pan\nage: 12",
output.data)
test "Serialization: Represent cyclic data structure":
@ -198,7 +202,7 @@ suite "Serialization":
var output = newStringStream()
dump(a, output, psBlockOnly, tsRootOnly)
assertStringEqual """%YAML 1.2
--- !nim:custom:Node &a
--- !example.net:Node &a
value: a
next:
value: b
@ -208,7 +212,7 @@ next:
test "Serialization: Load cyclic data structure":
let input = newStringStream("""%YAML 1.2
--- !nim:system:seq(nim:custom:Node)
--- !nim:system:seq(example.net:Node)
- &a
value: a
next: &b

View File

@ -126,7 +126,7 @@ type
##
## When `YamlParser <#YamlParser>`_ encounters tags not existing in the
## tag library, it will use
## `registerTagUri <#registerTagUri,TagLibrary,string>`_ to add
## `registerUri <#registerUri,TagLibrary,string>`_ to add
## the tag to the library.
##
## You can base your tag library on common tag libraries by initializing
@ -343,18 +343,6 @@ const
yamlTagRepositoryPrefix* = "tag:yaml.org,2002:"
yTagNimInt8* = 100.TagId ## tag for Nim's ``int8``
yTagNimInt16* = 101.TagId ## tag for Nim's ``int16``
yTagNimInt32* = 102.TagId ## tag for Nim's ``int32``
yTagNimInt64* = 103.TagId ## tag for Nim's ``int64``
yTagNimUInt8* = 104.TagId ## tag for Nim's ``uint8``
yTagNimUInt16* = 105.TagId ## tag for Nim's ``uint16``
yTagNimUInt32* = 106.TagId ## tag for Nim's ``uint32``
yTagNimUInt64* = 107.TagId ## tag for Nim's ``uint64``
yTagNimFloat32* = 108.TagId ## tag for Nim's ``float32``
yTagNimFloat64* = 109.TagId ## tag for Nim's ``float64``
yTagNimChar* = 110.TagId ## tag for Nim's ``char``
# interface
proc `==`*(left: YamlStreamEvent, right: YamlStreamEvent): bool {.raises: [].}