mirror of https://github.com/status-im/NimYAML.git
doc: extracted examples to own files
This commit is contained in:
parent
834c4b174a
commit
31ac201e41
|
@ -17,4 +17,6 @@ libyaml.dylib
|
|||
libyaml.so
|
||||
bench/json
|
||||
docout
|
||||
doc/rstPreproc
|
||||
doc/tmp.rst
|
||||
yaml-dev-kit
|
||||
|
|
14
config.nims
14
config.nims
|
@ -20,17 +20,21 @@ task serializationTests, "Run serialization tests":
|
|||
|
||||
task documentation, "Generate documentation":
|
||||
exec "mkdir -p docout"
|
||||
withDir "doc":
|
||||
exec r"nim c rstPreproc"
|
||||
exec r"./rstPreproc -o:tmp.rst index.txt"
|
||||
exec r"nim rst2html -o:../docout/index.html tmp.rst"
|
||||
exec r"./rstPreproc -o:tmp.rst api.txt"
|
||||
exec r"nim rst2html -o:../docout/api.html tmp.rst"
|
||||
exec r"./rstPreproc -o:tmp.rst serialization.txt"
|
||||
exec r"nim rst2html -o:../docout/serialization.html tmp.rst"
|
||||
exec "cp docutils.css style.css testing.html processing.svg ../docout"
|
||||
exec r"nim doc2 -o:docout/yaml.html --docSeeSrcUrl:https://github.com/flyx/NimYAML/blob/`git log -n 1 --format=%H` yaml"
|
||||
# bash! ah-ah \\ savior of the universe
|
||||
for file in listFiles("yaml"):
|
||||
let packageName = file[5..^5]
|
||||
exec r"nim doc2 -o:docout/yaml." & packageName &
|
||||
".html --docSeeSrcUrl:https://github.com/flyx/NimYAML/blob/yaml/`git log -n 1 --format=%H` " &
|
||||
file
|
||||
exec r"nim rst2html -o:docout/index.html doc/index.txt"
|
||||
exec r"nim rst2html -o:docout/api.html doc/api.txt"
|
||||
exec r"nim rst2html -o:docout/serialization.html doc/serialization.txt"
|
||||
exec "cp doc/docutils.css doc/style.css doc/testing.html doc/processing.svg docout"
|
||||
setCommand "nop"
|
||||
|
||||
task bench, "Benchmarking":
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import yaml
|
||||
type Mob = object
|
||||
level, experience: int32
|
||||
drops: seq[string]
|
||||
|
||||
setTagUri(Mob, "!Mob")
|
||||
setTagUri(seq[string], "!Drops")
|
||||
|
||||
var mob = Mob(level: 42, experience: 1800, drops:
|
||||
@["Sword of Mob Slaying"])
|
||||
var s = newFileStream("out.yaml", fmWrite)
|
||||
dump(mob, s,
|
||||
options = defineOptions(tagStyle = tsAll))
|
||||
s.close()
|
|
@ -0,0 +1,5 @@
|
|||
%YAML 1.2
|
||||
--- !Mob
|
||||
!nim:field level: !nim:system:int32 42
|
||||
!nim:field experience: !nim:system:int32 1800
|
||||
!nim:field drops: !Drops [!!str Sword of Mob Slaying]
|
|
@ -0,0 +1,13 @@
|
|||
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,
|
||||
options = defineOptions(style = psJson))
|
||||
s.close()
|
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
{
|
||||
"name": "Karl Koch",
|
||||
"age": 23
|
||||
},
|
||||
{
|
||||
"name": "Peter Pan",
|
||||
"age": 12
|
||||
}
|
||||
]
|
|
@ -0,0 +1,20 @@
|
|||
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()
|
|
@ -0,0 +1,11 @@
|
|||
%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
|
|
@ -0,0 +1,12 @@
|
|||
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()
|
|
@ -0,0 +1,8 @@
|
|||
%YAML 1.2
|
||||
--- !nim:system:seq(nim:custom:Person)
|
||||
-
|
||||
name: Karl Koch
|
||||
age: 23
|
||||
-
|
||||
name: Peter Pan
|
||||
age: 12
|
|
@ -0,0 +1,8 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
- this is a string
|
||||
- 42
|
||||
- false
|
||||
- !!str 23
|
||||
- !nim:demo:Person {name: Trillian}
|
||||
- !!null
|
|
@ -0,0 +1,37 @@
|
|||
import yaml
|
||||
type
|
||||
Person = object
|
||||
name: string
|
||||
|
||||
ContainerKind = enum
|
||||
ckString, ckInt, ckBool, ckPerson, ckNone
|
||||
|
||||
Container = object
|
||||
case kind: ContainerKind
|
||||
of ckString:
|
||||
strVal: string
|
||||
of ckInt:
|
||||
intVal: int
|
||||
of ckBool:
|
||||
boolVal: bool
|
||||
of ckPerson:
|
||||
personVal: Person
|
||||
of ckNone:
|
||||
discard
|
||||
|
||||
setTagUri(Person, "!nim:demo:Person")
|
||||
|
||||
# tell NimYAML to use Container as implicit type.
|
||||
# only possible with variant object types where
|
||||
# each branch contains at most one object.
|
||||
markAsImplicit(Container)
|
||||
|
||||
var list: seq[Container]
|
||||
|
||||
var s = newFileStream("in.yaml")
|
||||
load(s, list)
|
||||
s.close()
|
||||
|
||||
assert(list[0].kind == ckString)
|
||||
assert(list[0].strVal == "this is a string")
|
||||
# and so on
|
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
{
|
||||
"name": "Karl Koch",
|
||||
"age": 23
|
||||
},
|
||||
{
|
||||
"name": "Peter Pan",
|
||||
"age": 12
|
||||
}
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
import yaml
|
||||
type Person = object
|
||||
name : string
|
||||
age : int32
|
||||
|
||||
var personList: seq[Person]
|
||||
|
||||
var s = newFileStream("in.yaml")
|
||||
load(s, personList)
|
||||
s.close()
|
|
@ -0,0 +1,11 @@
|
|||
%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
|
|
@ -0,0 +1,12 @@
|
|||
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()
|
|
@ -0,0 +1,4 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
- { name: Karl Koch, age: 23 }
|
||||
- { name: Peter Pan, age: 12 }
|
|
@ -0,0 +1,9 @@
|
|||
import yaml
|
||||
type Person = object
|
||||
name : string
|
||||
age : int32
|
||||
|
||||
var personList: seq[Person]
|
||||
var s = newFileStream("in.yaml")
|
||||
load(s, personList)
|
||||
s.close()
|
|
@ -0,0 +1,16 @@
|
|||
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()
|
|
@ -0,0 +1,16 @@
|
|||
%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"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"Dumping Nim objects as YAML": [
|
||||
"dump-yaml", "out"
|
||||
],
|
||||
|
||||
"Loading Nim objects from YAML": [
|
||||
"load-yaml", "in"
|
||||
],
|
||||
|
||||
"Customizing output style" : [
|
||||
"outputstyle", "out"
|
||||
],
|
||||
|
||||
"Dumping reference types and cyclic structures": [
|
||||
"dump-reftypes", "out"
|
||||
],
|
||||
|
||||
"Loading reference types and cyclic structures": [
|
||||
"load-reftypes", "in"
|
||||
],
|
||||
|
||||
"Defining a custom tag uri for a type": [
|
||||
"customtag", "out"
|
||||
],
|
||||
|
||||
"Dumping Nim objects as JSON": [
|
||||
"dump-json", "out"
|
||||
],
|
||||
|
||||
"Loading Nim objects from JSON": [
|
||||
"load-json", "in"
|
||||
],
|
||||
|
||||
"Processing a Sequence of Heterogeneous Items": {
|
||||
"… With variant objects": [
|
||||
"implicit-variant", "in"
|
||||
],
|
||||
|
||||
"… With the Sequential API": [
|
||||
"sequential-api", "in"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
%YAML 1.2
|
||||
--- !!seq
|
||||
- this is a string
|
||||
- 42
|
||||
- false
|
||||
- !!str 23
|
||||
- !nim:demo:Person {name: Trillian}
|
|
@ -0,0 +1,51 @@
|
|||
import yaml
|
||||
type Person = object
|
||||
name: string
|
||||
|
||||
setTagUri(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 scalars
|
||||
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
|
||||
of 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()
|
463
doc/index.txt
463
doc/index.txt
|
@ -19,465 +19,4 @@ install it with `Nimble <https://github.com/nim-lang/nimble>`_:
|
|||
Quickstart
|
||||
==========
|
||||
|
||||
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>
|
||||
|
||||
.. 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
|
||||
import yaml
|
||||
type Mob = object
|
||||
level, experience: int32
|
||||
drops: seq[string]
|
||||
|
||||
setTagUri(Mob, "!Mob")
|
||||
setTagUri(seq[string], "!Drops")
|
||||
|
||||
var mob = Mob(level: 42, experience: 1800, drops:
|
||||
@["Sword of Mob Slaying"])
|
||||
var s = newFileStream("out.yaml", fmWrite)
|
||||
dump(mob, s,
|
||||
options = defineOptions(tagStyle = tsAll))
|
||||
s.close()
|
||||
|
||||
.. raw:: html
|
||||
</td><td>
|
||||
|
||||
.. code-block:: yaml
|
||||
YAML 1.2
|
||||
--- !Mob
|
||||
!nim:field level: !nim:system:int32 42
|
||||
!nim:field experience: !nim:system:int32 1800
|
||||
!nim:field drops: !Drops [!!str Sword of Mob Slaying]
|
||||
|
||||
.. 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)
|
||||
dump(personList, s,
|
||||
options = defineOptions(style = psJson))
|
||||
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
|
||||
}
|
||||
]
|
||||
|
||||
.. raw:: html
|
||||
</td></tr></tbody></table>
|
||||
|
||||
Processing a Sequence of Heterogeneous Items
|
||||
--------------------------------------------
|
||||
|
||||
… With variant objects
|
||||
......................
|
||||
|
||||
.. 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
|
||||
|
||||
ContainerKind = enum
|
||||
ckString, ckInt, ckBool, ckPerson, ckNone
|
||||
|
||||
Container = object
|
||||
case kind: ContainerKind
|
||||
of ckString:
|
||||
strVal: string
|
||||
of ckInt:
|
||||
intVal: int
|
||||
of ckBool:
|
||||
boolVal: bool
|
||||
of ckPerson:
|
||||
personVal: Person
|
||||
of ckNone:
|
||||
discard
|
||||
|
||||
setTagUri(Person, "!nim:demo:Person")
|
||||
|
||||
# tell NimYAML to use Container as implicit type.
|
||||
# only possible with variant object types where
|
||||
# each branch contains at most one object.
|
||||
markAsImplicit(Container)
|
||||
|
||||
var list: seq[Container]
|
||||
|
||||
var s = newFileStream("in.yaml")
|
||||
load(s, list)
|
||||
s.close()
|
||||
|
||||
assert(list[0].kind == ckString)
|
||||
assert(list[0].strVal == "this is a string")
|
||||
# and so on
|
||||
|
||||
.. raw:: html
|
||||
</td>
|
||||
<td>
|
||||
|
||||
.. code-block:: yaml
|
||||
%YAML 1.2
|
||||
---
|
||||
- this is a string
|
||||
- 42
|
||||
- false
|
||||
- !!str 23
|
||||
- !nim:demo:Person {name: Trillian}
|
||||
- !!null
|
||||
|
||||
.. raw:: html
|
||||
</td></tr></tbody></table>
|
||||
|
||||
… With the Sequential API
|
||||
.........................
|
||||
|
||||
.. 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
|
||||
|
||||
setTagUri(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 scalars
|
||||
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
|
||||
of 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}
|
||||
|
||||
.. raw:: html
|
||||
</td></tr></tbody></table>
|
||||
%examples/quickstart.json%/
|
|
@ -0,0 +1,127 @@
|
|||
## This is a tool for preprocessing rst files. Lines starting with ``%`` will
|
||||
## get substituted by nicely layouted included nim and yaml code.
|
||||
##
|
||||
## The syntax of substituted lines is ``'%' jsonfile '%' jsonpath``. *jsonfile*
|
||||
## shall be the path to a JSON file. *jsonpath* shall be a path to some node in
|
||||
## that JSON file.
|
||||
##
|
||||
## Usage:
|
||||
##
|
||||
## rstPreproc -o:path <infile>
|
||||
##
|
||||
## *path* is the output path. If omitted, it will be equal to infile with its
|
||||
## suffix substituted by ``.rst``. *infile* is the source rst file.
|
||||
|
||||
import parseopt2, json, streams, tables, strutils, os
|
||||
|
||||
var
|
||||
infile = ""
|
||||
path: string = nil
|
||||
for kind, key, val in getopt():
|
||||
case kind
|
||||
of cmdArgument:
|
||||
if infile == "":
|
||||
if key == "":
|
||||
echo "invalid input file with empty name!"
|
||||
quit 1
|
||||
infile = key
|
||||
else:
|
||||
echo "Only one input file is supported!"
|
||||
quit 1
|
||||
of cmdLongOption, cmdShortOption:
|
||||
case key
|
||||
of "out", "o":
|
||||
if isNil(path): path = val
|
||||
else:
|
||||
echo "Duplicate output path!"
|
||||
quit 1
|
||||
else:
|
||||
echo "Unknown option: ", key
|
||||
quit 1
|
||||
of cmdEnd: assert(false) # cannot happen
|
||||
|
||||
if infile == "":
|
||||
echo "Missing input file!"
|
||||
quit 1
|
||||
|
||||
if isNil(path):
|
||||
for i in countdown(infile.len - 1, 0):
|
||||
if infile[i] == '.':
|
||||
if infile[i..^1] == ".rst": path = infile & ".rst"
|
||||
else: path = infile[0..i] & "rst"
|
||||
break
|
||||
if isNil(path): path = infile & ".rst"
|
||||
|
||||
var tmpOut = newFileStream(path, fmWrite)
|
||||
|
||||
proc append(s: string) =
|
||||
tmpOut.writeLine(s)
|
||||
|
||||
proc gotoPath(root: JsonNode, path: string): JsonNode =
|
||||
doAssert path[0] == '/'
|
||||
if path.len == 1: return root
|
||||
doAssert root.kind == JObject
|
||||
for i in 1..<path.len:
|
||||
if path[i] == '/':
|
||||
return gotoPath(root.getFields()[path[1..<i]], path[i+1 .. ^1])
|
||||
return root.getFields()[path[1..^1]]
|
||||
|
||||
const headingChars = ['-', '`', ':', '\'']
|
||||
|
||||
proc outputExamples(node: JsonNode, prefix: string, level: int = 0) =
|
||||
case node.kind
|
||||
of JObject:
|
||||
for key, value in node.getFields():
|
||||
append(key)
|
||||
let headingChar = if level >= headingChars.len: headingChars[^1] else:
|
||||
headingChars[level]
|
||||
append(repeat(headingChar, key.len) & '\l')
|
||||
outputExamples(value, prefix, level + 1)
|
||||
of JArray:
|
||||
let elems = node.getElems()
|
||||
case elems.len
|
||||
of 2:
|
||||
append(".. raw:: html")
|
||||
append(" <table class=\"quickstart-example\"><thead><tr><th>code.nim</th>")
|
||||
append(" <th>" & elems[1].getStr() &
|
||||
".yaml</th></tr></thead><tbody><tr><td>\n")
|
||||
append(".. code:: nim")
|
||||
append(" :file: " & prefix & elems[0].getStr() & ".nim\n")
|
||||
append(".. raw:: html")
|
||||
append(" </td>\n <td>\n")
|
||||
append(".. code:: yaml")
|
||||
append(" :file: " & prefix & elems[0].getStr() & '.' &
|
||||
elems[1].getStr() & ".yaml\n")
|
||||
append(".. raw:: html")
|
||||
append(" </td></tr></tbody></table>\n")
|
||||
else:
|
||||
echo "Unexpected number of elements in array: ", elems.len
|
||||
quit 1
|
||||
else:
|
||||
echo "Unexpected node kind: ", node.kind
|
||||
quit 1
|
||||
|
||||
var lineNum = 0
|
||||
for line in infile.lines():
|
||||
if line.len > 0 and line[0] == '%':
|
||||
var
|
||||
jsonFile: string = nil
|
||||
jsonPath: string = nil
|
||||
for i in 1..<line.len:
|
||||
if line[i] == '%':
|
||||
jsonFile = line[1 .. i - 1]
|
||||
jsonPath = line[i + 1 .. ^1]
|
||||
break
|
||||
if isNil(jsonFile):
|
||||
echo "Second % missing in line " & $lineNum & "! content:\n"
|
||||
echo line
|
||||
quit 1
|
||||
let root = parseFile(jsonFile)
|
||||
var prefix = ""
|
||||
for i in countdown(jsonFile.len - 1, 0):
|
||||
if jsonFile[i] == '/':
|
||||
prefix = jsonFile[0..i]
|
||||
break
|
||||
outputExamples(root.gotoPath(jsonPath), prefix)
|
||||
else:
|
||||
append(line)
|
Loading…
Reference in New Issue