NimYAML/doc/index.txt

421 lines
8.7 KiB
Plaintext
Raw Normal View History

2016-01-13 21:43:12 +00:00
=======
NimYAML
=======
Introduction
============
2016-02-02 20:14:56 +00:00
**NimYAML** is a pure YAML implementation for Nim. It is able to read from and
write to YAML character streams, and to serialize from and construct to native
Nim types. It exclusively supports
`YAML 1.2 <#http://www.yaml.org/spec/1.2/spec.html>`_.
2016-02-16 19:44:40 +00:00
Source code can be found on `GitHub <https://github.com/flyx/NimYAML>`_. You can
install it with `Nimble <https://github.com/nim-lang/nimble>`_:
.. code-block:: bash
2016-03-20 21:58:39 +00:00
nimble install nimyaml
2016-02-16 19:44:40 +00:00
Quickstart
2016-03-20 21:58:39 +00:00
==========
Dumping Nim objects as YAML
--------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>out.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type Person = object
name : string
age : int32
var personList = newSeq[Person]()
personList.add(Person(name: "Karl Koch", age: 23))
personList.add(Person(name: "Peter Pan", age: 12))
var s = newFileStream("out.yaml", fmWrite)
dump(personList, s)
s.close()
.. raw:: html
</td>
<td>
.. code-block:: yaml
%YAML 1.2
--- !nim:system:seq(nim:custom:Person)
-
name: Karl Koch
age: 23
-
name: Peter Pan
age: 12
.. raw:: html
</td></tr></tbody></table>
Loading Nim objects from YAML
----------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>in.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type Person = object
name : string
age : int32
var personList: seq[Person]
var s = newFileStream("in.yaml")
load(s, personList)
s.close()
.. raw:: html
</td>
<td>
.. code-block:: yaml
%YAML 1.2
---
- { name: Karl Koch, age: 23 }
- { name: Peter Pan, age: 12 }
.. raw:: html
</td></tr></tbody></table>
Customizing output style
----------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>out.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type Person = object
name: string
age: int32
var personList: seq[Person]
personList.add(Person(name: "Karl Koch", age: 23))
personList.add(Person(name: "Peter Pan", age: 12))
var s = newFileStream("out.yaml")
dump(personList, s, options = defineOptions(
style = psCanonical,
indentationStep = 3,
newlines = nlLF,
outputVersion = ov1_1))
s.close()
.. raw:: html
</td><td>
.. code-block:: yaml
%YAML 1.1
--- !nim:system:seq(nim:custom:Person)
[
!nim:custom:Person {
? !!str "name"
: !!str "Karl Koch",
? !!str "age"
: !nim:system:int32 "23"
},
!nim:custom:Person {
? !!str "name"
: !!str "Peter Pan",
? !!str "age"
: !nim:system:int32 "12"
}
]
.. raw:: html
</td></tr></tbody></table>
Dumping reference types and cyclic structures
---------------------------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>out.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type
Node = ref NodeObj
NodeObj = object
name: string
left, right: Node
var node1, node2, node3: Node
new(node1); new(node2); new(node3)
node1.name = "Node 1"
node2.name = "Node 2"
node3.name = "Node 3"
node1.left = node2
node1.right = node3
node2.right = node3
node3.left = node1
var s = newFileStream("out.yaml", fmWrite)
dump(node1, s)
s.close()
.. raw:: html
</td><td>
2016-03-20 21:58:39 +00:00
.. code-block:: yaml
%YAML 1.2
--- !nim:custom:NodeObj &a
name: Node 1
left:
name: Node 2
left: !!null ~
right: &b
name: Node 3
left: *a
right: !!null ~
right: *b
.. raw:: html
</td></tr></tbody></table>
Loading reference types and cyclic structures
---------------------------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>in.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type
Node = ref NodeObj
NodeObj = object
name: string
left, right: Node
var node1: Node
var s = newFileStream("in.yaml")
load(s, node1)
s.close()
.. raw:: html
</td><td>
.. code-block:: yaml
%YAML 1.2
--- !nim:custom:NodeObj &a
name: Node 1
left:
name: Node 2
left: ~
right: &b
name: Node 3
left: *a
right: ~
right: *b
.. raw:: html
</td></tr></tbody></table>
Defining a custom tag uri for a type
------------------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>out.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
2016-03-20 21:58:39 +00:00
import yaml
type Mob = object
2016-03-21 20:15:38 +00:00
level, experience: int32
drops: seq[string]
2016-03-20 21:58:39 +00:00
setTagUriForType(Mob, "!Mob")
2016-03-21 20:15:38 +00:00
setTagUriForType(seq[string], "!Drops")
2016-03-20 21:58:39 +00:00
2016-03-21 20:15:38 +00:00
var mob = Mob(level: 42, experience: 1800, drops:
@["Sword of Mob Slaying"])
2016-03-20 21:58:39 +00:00
var s = newFileStream("out.yaml", fmWrite)
2016-03-21 20:15:38 +00:00
dump(mob, s,
options = defineOptions(tagStyle = tsAll))
2016-03-20 21:58:39 +00:00
s.close()
.. raw:: html
</td><td>
.. code-block:: yaml
YAML 1.2
2016-03-20 21:58:39 +00:00
--- !Mob
!nim:field level: !nim:system:int32 42
!nim:field experience: !nim:system:int32 1800
!nim:field drops: !Drops [!!str Sword of Mob Slaying]
2016-03-20 21:58:39 +00:00
.. raw:: html
</td></tr></tbody></table>
Dumping Nim objects as JSON
---------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>out.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type Person = object
name : string
age : int32
var personList = newSeq[Person]()
personList.add(Person(name: "Karl Koch", age: 23))
personList.add(Person(name: "Peter Pan", age: 12))
var s = newFileStream("out.yaml", fmWrite)
2016-03-21 20:15:38 +00:00
dump(personList, s,
options = defineOptions(style = psJson))
2016-03-20 21:58:39 +00:00
s.close()
.. raw:: html
</td>
<td>
.. code-block:: yaml
[
{
"name": "Karl Koch",
"age": 23
},
{
"name": "Peter Pan",
"age": 12
}
]
.. raw:: html
</td></tr></tbody></table>
Loading Nim objects from JSON
-----------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>in.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type Person = object
name : string
age : int32
var personList: seq[Person]
var s = newFileStream("in.yaml")
load(s, personList)
s.close()
.. raw:: html
</td>
<td>
.. code-block:: yaml
[
{
"name": "Karl Koch",
"age": 23
},
{
"name": "Peter Pan",
"age": 12
}
]
2016-03-25 22:12:00 +00:00
.. raw:: html
</td></tr></tbody></table>
Processing a Sequence of Heterogeneous Items
--------------------------------------------
.. raw:: html
<table class="quickstart-example"><thead><tr><th>code.nim</th>
<th>in.yaml</th></tr></thead><tbody><tr><td>
.. code-block:: nim
import yaml
type Person = object
name: string
setTagUriForType(Person, "!nim:demo:Person",
yTagPerson)
var
s = newFileStream("in.yaml", fmRead)
context = newConstructionContext()
parser = newYamlParser(serializationTagLibrary)
events = parser.parse(s)
assert events.next().kind == yamlStartDoc
assert events.next().kind == yamlStartSeq
var nextEvent = events.peek()
while nextEvent.kind != yamlEndSeq:
var curTag = nextEvent.tag()
if curTag == yTagQuestionMark:
# we only support implicitly tagged scalar events
assert nextEvent.kind == yamlScalar
case guessType(nextEvent.scalarContent)
of yTypeInteger: curTag = yTagInteger
of yTypeBoolTrue, yTypeBoolFalse:
curTag = yTagBoolean
of yTypeUnknown: curTag = yTagString
else: assert false, "Type not supported!"
elif curTag == yTagExclamationMark:
curTag = yTagString
case curTag
of yTagString:
var s: string
events.constructChild(context, s)
echo "got string: ", s
of yTagInteger:
var i: int32
events.constructChild(context, i)
echo "got integer: ", i
of yTagBoolean:
var b: bool
events.constructChild(context, b)
echo "got boolean: ", b
else:
# non-standard tag ids are not available
# at compile time
if curTag == yTagPerson:
var p: Person
events.constructChild(context, p)
echo "got Person with name: ", p.name
else: assert false, "unsupported tag: " & $curTag
nextEvent = events.peek()
assert events.next().kind == yamlEndSeq
assert events.next().kind == yamlEndDoc
assert events.finished()
s.close()
.. raw:: html
</td>
<td>
.. code-block:: yaml
%YAML 1.2
--- !!seq
- this is a string
- 42
- false
- !!str 23
- !nim:demo:Person {name: Trillian}
2016-03-20 21:58:39 +00:00
.. raw:: html
</td></tr></tbody></table>