updated docs

This commit is contained in:
Felix Krause 2020-06-26 22:36:52 +02:00
parent bce3981849
commit e4b3e8347a
4 changed files with 46 additions and 53 deletions

View File

@ -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)

View File

@ -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
=======================

View File

@ -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>

View File

@ -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.}