mirror of https://github.com/status-im/NimYAML.git
Implemented serialization of OrderedMap
This commit is contained in:
parent
06faf4966d
commit
5ec086081c
|
@ -235,16 +235,14 @@ proc representObject*[T](value: seq[T], ts: TagStyle,
|
||||||
## represents a Nim seq as YAML sequence
|
## represents a Nim seq as YAML sequence
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
yield YamlStreamEvent(kind: yamlStartSeq,
|
yield startSeqEvent(tag)
|
||||||
seqTag: tag,
|
|
||||||
seqAnchor: yAnchorNone)
|
|
||||||
for item in value:
|
for item in value:
|
||||||
var events = representChild(item, childTagStyle, c)
|
var events = representChild(item, childTagStyle, c)
|
||||||
while true:
|
while true:
|
||||||
let event = events()
|
let event = events()
|
||||||
if finished(events): break
|
if finished(events): break
|
||||||
yield event
|
yield event
|
||||||
yield YamlStreamEvent(kind: yamlEndSeq)
|
yield endSeqEvent()
|
||||||
|
|
||||||
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
|
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
|
||||||
try:
|
try:
|
||||||
|
@ -252,7 +250,7 @@ proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
|
||||||
safeTagUri(yamlTag(V)) & ")"
|
safeTagUri(yamlTag(V)) & ")"
|
||||||
result = lazyLoadTag(uri)
|
result = lazyLoadTag(uri)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# cannot happen (theoretically, you known)
|
# cannot happen (theoretically, you know)
|
||||||
assert(false)
|
assert(false)
|
||||||
|
|
||||||
proc constructObject*[K, V](s: var YamlStream, c: ConstructionContext,
|
proc constructObject*[K, V](s: var YamlStream, c: ConstructionContext,
|
||||||
|
@ -270,6 +268,8 @@ proc constructObject*[K, V](s: var YamlStream, c: ConstructionContext,
|
||||||
value: V
|
value: V
|
||||||
constructChild(s, c, key)
|
constructChild(s, c, key)
|
||||||
constructChild(s, c, value)
|
constructChild(s, c, value)
|
||||||
|
if result.contains(key):
|
||||||
|
raise newException(YamlConstructionError, "Duplicate table key!")
|
||||||
result[key] = value
|
result[key] = value
|
||||||
discard s.next()
|
discard s.next()
|
||||||
|
|
||||||
|
@ -278,9 +278,7 @@ proc representObject*[K, V](value: Table[K, V], ts: TagStyle,
|
||||||
## represents a Nim Table as YAML mapping
|
## represents a Nim Table as YAML mapping
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
yield YamlStreamEvent(kind: yamlStartMap,
|
yield startMapEvent(tag)
|
||||||
mapTag: tag,
|
|
||||||
mapAnchor: yAnchorNone)
|
|
||||||
for key, value in value.pairs:
|
for key, value in value.pairs:
|
||||||
var events = representChild(key, childTagStyle, c)
|
var events = representChild(key, childTagStyle, c)
|
||||||
while true:
|
while true:
|
||||||
|
@ -292,7 +290,63 @@ proc representObject*[K, V](value: Table[K, V], ts: TagStyle,
|
||||||
let event = events()
|
let event = events()
|
||||||
if finished(events): break
|
if finished(events): break
|
||||||
yield event
|
yield event
|
||||||
yield YamlStreamEvent(kind: yamlEndMap)
|
yield endMapEvent()
|
||||||
|
|
||||||
|
proc yamlTag*[K, V](T: typedesc[OrderedTable[K, V]]): TagId
|
||||||
|
{.inline, raises: [].} =
|
||||||
|
try:
|
||||||
|
let uri = "!nim:tables:OrderedTable(" & safeTagUri(yamlTag(K)) & "," &
|
||||||
|
safeTagUri(yamlTag(V)) & ")"
|
||||||
|
result = lazyLoadTag(uri)
|
||||||
|
except KeyError:
|
||||||
|
# cannot happen (theoretically, you know)
|
||||||
|
assert(false)
|
||||||
|
|
||||||
|
proc constructObject*[K, V](s: var YamlStream, c: ConstructionContext,
|
||||||
|
result: var OrderedTable[K, V])
|
||||||
|
{.raises: [YamlConstructionError, YamlStreamError].} =
|
||||||
|
## constructs a Nim OrderedTable from a YAML mapping
|
||||||
|
let event = s.next()
|
||||||
|
if event.kind != yamlStartSeq:
|
||||||
|
raise newException(YamlConstructionError, "Expected seq start, got " &
|
||||||
|
$event.kind)
|
||||||
|
result = initOrderedTable[K, V]()
|
||||||
|
while s.peek.kind != yamlEndSeq:
|
||||||
|
var
|
||||||
|
key: K
|
||||||
|
value: V
|
||||||
|
if s.next().kind != yamlStartMap:
|
||||||
|
raise newException(YamlConstructionError,
|
||||||
|
"Expected map start, got " & $event.kind)
|
||||||
|
constructChild(s, c, key)
|
||||||
|
constructChild(s, c, value)
|
||||||
|
if s.next().kind != yamlEndMap:
|
||||||
|
raise newException(YamlConstructionError,
|
||||||
|
"Expected map end, got " & $event.kind)
|
||||||
|
if result.contains(key):
|
||||||
|
raise newException(YamlConstructionError, "Duplicate table key!")
|
||||||
|
result.add(key, value)
|
||||||
|
discard s.next()
|
||||||
|
|
||||||
|
proc representObject*[K, V](value: OrderedTable[K, V], ts: TagStyle,
|
||||||
|
c: SerializationContext, tag: TagId): RawYamlStream {.raises: [].} =
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
|
yield startSeqEvent(tag)
|
||||||
|
for key, value in value.pairs:
|
||||||
|
yield startMapEvent()
|
||||||
|
var events = representChild(key, childTagStyle, c)
|
||||||
|
while true:
|
||||||
|
let event = events()
|
||||||
|
if finished(events): break
|
||||||
|
yield event
|
||||||
|
events = representChild(value, childTagStyle, c)
|
||||||
|
while true:
|
||||||
|
let event = events()
|
||||||
|
if finished(events): break
|
||||||
|
yield event
|
||||||
|
yield endMapEvent()
|
||||||
|
yield endSeqEvent()
|
||||||
|
|
||||||
template yamlTag*(T: typedesc[object|enum]): expr =
|
template yamlTag*(T: typedesc[object|enum]): expr =
|
||||||
var uri = when compiles(yamlTagId(T)): yamlTagId(T) else:
|
var uri = when compiles(yamlTagId(T)): yamlTagId(T) else:
|
||||||
|
@ -546,13 +600,13 @@ proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
||||||
var
|
var
|
||||||
context = newSerializationContext(a)
|
context = newSerializationContext(a)
|
||||||
objStream = iterator(): YamlStreamEvent =
|
objStream = iterator(): YamlStreamEvent =
|
||||||
yield YamlStreamEvent(kind: yamlStartDoc)
|
yield startDocEvent()
|
||||||
var events = representChild(value, ts, context)
|
var events = representChild(value, ts, context)
|
||||||
while true:
|
while true:
|
||||||
let e = events()
|
let e = events()
|
||||||
if finished(events): break
|
if finished(events): break
|
||||||
yield e
|
yield e
|
||||||
yield YamlStreamEvent(kind: yamlEndDoc)
|
yield endDocEvent()
|
||||||
if a == asTidy:
|
if a == asTidy:
|
||||||
var objQueue = newSeq[YamlStreamEvent]()
|
var objQueue = newSeq[YamlStreamEvent]()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -51,7 +51,8 @@ proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
template assertStringEqual(expected, actual: string) =
|
template assertStringEqual(expected, actual: string) =
|
||||||
for i in countup(0, min(expected.len, actual.len)):
|
for i in countup(0, min(expected.len, actual.len)):
|
||||||
if expected[i] != actual[i]:
|
if expected[i] != actual[i]:
|
||||||
echo "string mismatch at character #", i, ":"
|
echo "string mismatch at character #", i, "(expected:\'",
|
||||||
|
expected[i], "\', was \'", actual[i], "\'):"
|
||||||
echo "expected:\n", expected, "\nactual:\n", actual
|
echo "expected:\n", expected, "\nactual:\n", actual
|
||||||
assert(false)
|
assert(false)
|
||||||
|
|
||||||
|
@ -98,6 +99,41 @@ suite "Serialization":
|
||||||
"%YAML 1.2\n--- \n23: dreiundzwanzig\n42: zweiundvierzig",
|
"%YAML 1.2\n--- \n23: dreiundzwanzig\n42: zweiundvierzig",
|
||||||
output.data)
|
output.data)
|
||||||
|
|
||||||
|
test "Serialization: Load OrderedTable[tuple[int32, int32], string]":
|
||||||
|
let input = newStringStream("- {a: 23, b: 42}: drzw\n- {a: 13, b: 47}: drsi")
|
||||||
|
var result: OrderedTable[tuple[a, b: int32], string]
|
||||||
|
load(input, result)
|
||||||
|
var i = 0
|
||||||
|
for key, value in result.pairs:
|
||||||
|
case i
|
||||||
|
of 0:
|
||||||
|
assert key == (a: 23'i32, b: 42'i32)
|
||||||
|
assert value == "drzw"
|
||||||
|
of 1:
|
||||||
|
assert key == (a: 13'i32, b: 47'i32)
|
||||||
|
assert value == "drsi"
|
||||||
|
else: assert false
|
||||||
|
i.inc()
|
||||||
|
|
||||||
|
test "Serialization: Represent OrderedTable[tuple[int32, int32], string]":
|
||||||
|
var input = initOrderedTable[tuple[a, b: int32], string]()
|
||||||
|
input.add((a: 23'i32, b: 42'i32), "dreiundzwanzigzweiundvierzig")
|
||||||
|
input.add((a: 13'i32, b: 47'i32), "dreizehnsiebenundvierzig")
|
||||||
|
var output = newStringStream()
|
||||||
|
dump(input, output, tsRootOnly, asTidy, blockOnly)
|
||||||
|
assertStringEqual("""%YAML 1.2
|
||||||
|
--- !nim:tables:OrderedTable(nim:tuple(nim:system:int32,nim:system:int32),tag:yaml.org,2002:str)
|
||||||
|
-
|
||||||
|
?
|
||||||
|
a: 23
|
||||||
|
b: 42
|
||||||
|
: dreiundzwanzigzweiundvierzig
|
||||||
|
-
|
||||||
|
?
|
||||||
|
a: 13
|
||||||
|
b: 47
|
||||||
|
: dreizehnsiebenundvierzig""", output.data)
|
||||||
|
|
||||||
test "Serialization: Load Sequences in Sequence":
|
test "Serialization: Load Sequences in Sequence":
|
||||||
let input = newStringStream(" - [1, 2, 3]\n - [4, 5]\n - [6]")
|
let input = newStringStream(" - [1, 2, 3]\n - [4, 5]\n - [6]")
|
||||||
var result: seq[seq[int32]]
|
var result: seq[seq[int32]]
|
||||||
|
|
Loading…
Reference in New Issue