Support array types. Updated documentation

This commit is contained in:
Felix Krause 2016-04-03 11:29:49 +02:00
parent a267f73e0a
commit f2c83cc170
3 changed files with 55 additions and 5 deletions

View File

@ -66,11 +66,11 @@ To support new scalar types, you must implement the ``constructObject()`` and
Collection Types
----------------
NimYAML supports Nim's ``seq`` and ``Table`` types out of the box. Unlike the
native YAML types ``!!seq`` and ``!!map``, ``seq`` and ``Table`` define the type
of all their 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`` 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:
.. code-block:: yaml

View File

@ -259,6 +259,42 @@ proc representObject*[T](value: seq[T]|set[T], ts: TagStyle,
yield event
yield endSeqEvent()
proc yamlTag*[I, V](T: typedesc[array[I, V]]): TagId {.inline, raises: [].} =
const rangeName = name(I)
let uri = "!nim:system:array(" & rangeName[6..rangeName.high()] & "," &
safeTagUri(yamlTag(V)) & ')'
result = lazyLoadTag(uri)
proc constructObject*[I, T](s: var YamlStream, c: ConstructionContext,
result: var array[I, T])
{.raises: [YamlConstructionError, YamlStreamError].} =
## constructs a Nim array from a YAML sequence
var event = s.next()
if event.kind != yamlStartSeq:
raise newException(YamlConstructionError, "Expected sequence start")
for index in low(I)..high(I):
event = s.peek()
if event.kind == yamlEndSeq:
raise newException(YamlConstructionError, "Too few array values")
constructChild(s, c, result[index])
event = s.next()
if event.kind != yamlEndSeq:
raise newException(YamlConstructionError, "Too much array values")
proc representObject*[I, T](value: array[I, T], ts: TagStyle,
c: SerializationContext, tag: TagId): RawYamlStream {.raises: [].} =
## represents a Nim array as YAML sequence
result = iterator(): YamlStreamEvent =
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
yield startSeqEvent(tag)
for item in value:
var events = representChild(item, childTagStyle, c)
while true:
let event = events()
if finished(events): break
yield event
yield endSeqEvent()
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
try:
let uri = "!nim:tables:Table(" & safeTagUri(yamlTag(K)) & "," &

View File

@ -92,6 +92,20 @@ suite "Serialization":
var output = newStringStream()
dump(input, output, tsNone, asTidy, blockOnly)
assertStringEqual "%YAML 1.2\n--- \n- a\n- b", output.data
test "Serialization: Load array":
let input = newStringStream("- 23\n- 42\n- 47")
var result: array[0..2, int32]
load(input, result)
assert result[0] == 23
assert result[1] == 42
assert result[2] == 47
test "Serialization: Represent array":
let input = [23'i32, 42'i32, 47'i32]
var output = newStringStream()
dump(input, output, tsNone, asTidy, blockOnly)
assertStringEqual "%YAML 1.2\n--- \n- 23\n- 42\n- 47", output.data
test "Serialization: Load Table[int, string]":
let input = newStringStream("23: dreiundzwanzig\n42: zweiundvierzig")