mirror of https://github.com/status-im/NimYAML.git
updated docs
This commit is contained in:
parent
bce3981849
commit
e4b3e8347a
|
@ -17,11 +17,11 @@
|
|||
## available as source files for automatic testing. This way, we can make sure
|
||||
## that the code in the docs actually works.
|
||||
|
||||
import parseopt2, streams, tables, strutils, os
|
||||
import parseopt2, streams, tables, strutils, os, options
|
||||
|
||||
var
|
||||
infile = ""
|
||||
path: string = nil
|
||||
path = none(string)
|
||||
for kind, key, val in getopt():
|
||||
case kind
|
||||
of cmdArgument:
|
||||
|
@ -36,7 +36,7 @@ for kind, key, val in getopt():
|
|||
of cmdLongOption, cmdShortOption:
|
||||
case key
|
||||
of "out", "o":
|
||||
if isNil(path): path = val
|
||||
if path.isNone: path = some(val)
|
||||
else:
|
||||
echo "Duplicate output path!"
|
||||
quit 1
|
||||
|
@ -49,15 +49,15 @@ if infile == "":
|
|||
echo "Missing input file!"
|
||||
quit 1
|
||||
|
||||
if isNil(path):
|
||||
if path.isNone:
|
||||
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"
|
||||
if infile[i..^1] == ".rst": path = some(infile & ".rst")
|
||||
else: path = some(infile[0..i] & "rst")
|
||||
break
|
||||
if isNil(path): path = infile & ".rst"
|
||||
if path.isNone: path = some(infile & ".rst")
|
||||
|
||||
var tmpOut = newFileStream(path, fmWrite)
|
||||
var tmpOut = newFileStream(path.get(), fmWrite)
|
||||
|
||||
proc append(s: string) =
|
||||
tmpOut.writeLine(s)
|
||||
|
@ -118,17 +118,17 @@ var lineNum = 0
|
|||
for line in infile.lines():
|
||||
if line.len > 0 and line[0] == '%':
|
||||
var
|
||||
srcPath: string = nil
|
||||
srcPath = none(string)
|
||||
level = 0
|
||||
for i in 1..<line.len:
|
||||
if line[i] == '%':
|
||||
srcPath = line[1 .. i - 1]
|
||||
srcPath = some(line[1 .. i - 1])
|
||||
level = parseInt(line[i + 1 .. ^1])
|
||||
break
|
||||
if isNil(srcPath):
|
||||
if srcPath.isNone:
|
||||
echo "Second % missing in line " & $lineNum & "! content:\n"
|
||||
echo line
|
||||
quit 1
|
||||
outputExamples("snippets" / srcPath, level)
|
||||
outputExamples("snippets" / srcPath.get(), level)
|
||||
else:
|
||||
append(line)
|
||||
|
|
|
@ -72,28 +72,26 @@ supported.
|
|||
To support new scalar types, you must implement the ``constructObject()`` and
|
||||
``representObject()`` procs on that type (see below).
|
||||
|
||||
Collection Types
|
||||
----------------
|
||||
Container Types
|
||||
---------------
|
||||
|
||||
NimYAML supports Nim's ``array``, ``set``, ``seq``, ``Table`` and
|
||||
``OrderedTable`` types out of the box. Unlike the native YAML types ``!!seq``
|
||||
and ``!!map``, Nim's collection types define the type of all their contained
|
||||
items (or keys and values). So YAML objects with heterogeneous types in them
|
||||
cannot be loaded to Nim collection types. For example, this sequence:
|
||||
NimYAML supports Nim's ``array``, ``set``, ``seq``, ``Table``, ``OrderedTable``
|
||||
and ``Option`` types out of the box. While YAML's standard types ``!!seq`` and
|
||||
``!!map`` allow arbitrarily typed content, in Nim the contained type must be
|
||||
known at compile time. Therefore, Nim cannot load ``!!seq`` and ``!!map``.
|
||||
|
||||
However, it doesn't need to. For example, if you have a YAML file like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
%YAML 1.2
|
||||
--- !!seq
|
||||
- !!int 1
|
||||
- !!string foo
|
||||
---
|
||||
- 1
|
||||
- 2
|
||||
|
||||
Cannot be loaded to a Nim ``seq``. For this reason, you cannot load YAML's
|
||||
native ``!!map`` and ``!!seq`` types directly into Nim types. However, you can
|
||||
use variant object types to process heterogeneous value lists, see below.
|
||||
|
||||
Nim ``seq`` types may be ``nil``. This is handled by serializing them to an
|
||||
empty scalar with the tag ``!nim:nil:seq``.
|
||||
You can simply load it into a `seq[int]`. If your YAML file contains differently
|
||||
typed values in the same collection, you can use an implicit variant object, see
|
||||
below.
|
||||
|
||||
Reference Types
|
||||
---------------
|
||||
|
@ -182,7 +180,7 @@ list in order to load it:
|
|||
type
|
||||
ContainerKind = enum
|
||||
ckInt, ckString, ckNone
|
||||
Container = object
|
||||
Container {.implicit.} = object
|
||||
case kind: ContainerKind
|
||||
of ckInt:
|
||||
intVal: int
|
||||
|
@ -191,14 +189,12 @@ list in order to load it:
|
|||
of ckNone:
|
||||
discard
|
||||
|
||||
markAsImplicit(Container)
|
||||
|
||||
var
|
||||
list: seq[Container]
|
||||
s = newFileStream("in.yaml")
|
||||
load(s, list)
|
||||
|
||||
``markAsImplicit`` tells NimYAML that you want to use the type ``Container``
|
||||
``{.implicit.}`` tells NimYAML that you want to use the type ``Container``
|
||||
implicitly, i.e. its fields are not visible in YAML, and are set dependent on
|
||||
the value type that gets loaded into it. The type ``Container`` must fullfil the
|
||||
following requirements:
|
||||
|
@ -251,11 +247,8 @@ for example use it on a certain ``seq`` type:
|
|||
Customizing Field Handling
|
||||
==========================
|
||||
|
||||
NimYAML allows the user to specify special handling of certain object fields.
|
||||
This configuration will be applied at compile time when NimYAML generates the
|
||||
(de)serialization code for an object type. It is important that the
|
||||
configuration happens before any YAML operations (e.g. ``load`` or ``dump``) are
|
||||
executed on a variable of the object type.
|
||||
NimYAML allows the user to specify special handling of certain object fields via
|
||||
annotation pragmas.
|
||||
|
||||
Transient Fields
|
||||
----------------
|
||||
|
@ -271,27 +264,23 @@ Example:
|
|||
|
||||
type MyObject: object
|
||||
storable: string
|
||||
temporary: string
|
||||
|
||||
markAsTransient(MyObject, temporary)
|
||||
temporary {.transient.}: string
|
||||
|
||||
Default Values
|
||||
--------------
|
||||
|
||||
When you load YAML that has been written by a human, you might want to allow the
|
||||
user to omit certain fields, which should then be filled with a default value.
|
||||
You can do that like this:
|
||||
When you load YAML, you might want to allow for the omission certain fields,
|
||||
which should then be filled with a default value. You can do that like this:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
type MyObject: object
|
||||
required: string
|
||||
optional: string
|
||||
optional {.defaultVal: "default value".}: string
|
||||
|
||||
setDefaultValue(MyObject, optional, "default value")
|
||||
|
||||
Whenever ``MyObject`` now is loaded and the input stream does not contain the
|
||||
field ``optional``, that field will be set to the value ``"default value"``.
|
||||
Whenever a value of type ``MyObject`` now is loaded and the input stream does
|
||||
not contain the field ``optional``, that field will be set to the value
|
||||
``"default value"``.
|
||||
|
||||
Customize Serialization
|
||||
=======================
|
||||
|
|
|
@ -126,6 +126,7 @@ doc.file = """
|
|||
<li><a href="yaml.parser.html">yaml.parser</a></li>
|
||||
<li><a href="yaml.presenter.html">yaml.presenter</a></li>
|
||||
<li><a href="yaml.serialization.html">yaml.serialization</a></li>
|
||||
<li><a href="yaml.annotations.html">yaml.annotations</a></li>
|
||||
<li><a href="yaml.stream.html">yaml.stream</a></li>
|
||||
<li><a href="yaml.taglib.html">yaml.taglib</a></li>
|
||||
<li><a href="yaml.tojson.html">yaml.tojson</a></li>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
template defaultVal*(value : typed) {.pragma.}
|
||||
## This annotation can be assigned to an object field. During deserialization,
|
||||
## if no value for this field is given, the `value` parameter of this
|
||||
## if no value for this field is given, the ``value`` parameter of this
|
||||
## annotation is used as value.
|
||||
##
|
||||
## Example usage:
|
||||
|
@ -24,7 +24,7 @@ template defaultVal*(value : typed) {.pragma.}
|
|||
## c {.defaultVal: (1,2).}: tuple[x, y: int]
|
||||
|
||||
template transient*() {.pragma.}
|
||||
## This annotation can be assigned to an object field. Any object field
|
||||
## This annotation can be put on an object field. Any object field
|
||||
## carrying this annotation will not be serialized to YAML and cannot be given
|
||||
## a value when deserializing. Giving a value for this field during
|
||||
## deserialization is an error.
|
||||
|
@ -39,14 +39,17 @@ template transient*() {.pragma.}
|
|||
## markAsTransient(MyObject, c)
|
||||
|
||||
template ignore*(keys : openarray[string]) {.pragma.}
|
||||
## This annotation can be assigned to an object type. All keys with the given
|
||||
## This annotation can be put on an object type. All keys with the given
|
||||
## names in the input YAML mapping will be ignored when deserializing a value
|
||||
## of this type. This can be used to ignore parts of the YAML structure.
|
||||
##
|
||||
## You may use it with an empty list (``{.ignore: [].}``) to ignore *all*
|
||||
## unknown keys.
|
||||
##
|
||||
## Example usage:
|
||||
##
|
||||
## .. code-block::
|
||||
## type MyObject {.ignore("c").} = object
|
||||
## type MyObject {.ignore: ["c"].} = object
|
||||
## a, b: string
|
||||
|
||||
template implicit*() {.pragma.}
|
||||
|
|
Loading…
Reference in New Issue