Properly handle ytsRootOnly

* Yield tag of custom type serialization when using ytsRootOnly,
   but don't yield tags of map keys or values
 * Yield proper tag of Table[K, V] serialization if requested
 * renamed dumper.nim to presenter.nim to conform to YAML spec
This commit is contained in:
Felix Krause 2016-01-04 22:18:55 +01:00
parent 507c621aaf
commit aa98c5863e
4 changed files with 47 additions and 42 deletions

View File

@ -346,4 +346,4 @@ include private.tagLibrary
include private.events include private.events
include private.sequential include private.sequential
include private.json include private.json
include private.dumper include private.presenter

View File

@ -39,7 +39,7 @@ static:
for i in 0..numFields - 1: for i in 0..numFields - 1:
yield (name: identDefs[i], t: identDefs[^2]) yield (name: identDefs[i], t: identDefs[^2])
template presentTag(t: typedesc): TagId {.dirty.} = template presentTag(t: typedesc, tagStyle: YamlTagStyle): TagId =
if tagStyle == ytsNone: yTagQuestionMark else: yamlTag(t) if tagStyle == ytsNone: yTagQuestionMark else: yamlTag(t)
proc lazyLoadTag*(uri: string): TagId {.inline.} = proc lazyLoadTag*(uri: string): TagId {.inline.} =
@ -124,14 +124,22 @@ macro make_serializable*(types: stmt): stmt =
newIdentDefs(newIdentNode("tagStyle"), newIdentDefs(newIdentNode("tagStyle"),
newIdentNode("YamlTagStyle"), newIdentNode("YamlTagStyle"),
newIdentNode("ytsNone"))]) newIdentNode("ytsNone"))])
var iterBody = newStmtList(newNimNode(nnkYieldStmt).add( var iterBody = newStmtList(
newLetStmt(newIdentNode("childTagStyle"), newNimNode(nnkIfExpr).add(
newNimNode(nnkElifExpr).add(
newNimNode(nnkInfix).add(newIdentNode("=="),
newIdentNode("tagStyle"), newIdentNode("ytsRootOnly")),
newIdentNode("ytsNone")
), newNimNode(nnkElseExpr).add(newIdentNode("tagStyle")))),
newNimNode(nnkYieldStmt).add(
newNimNode(nnkObjConstr).add(newIdentNode("YamlStreamEvent"), newNimNode(nnkObjConstr).add(newIdentNode("YamlStreamEvent"),
newNimNode(nnkExprColonExpr).add(newIdentNode("kind"), newNimNode(nnkExprColonExpr).add(newIdentNode("kind"),
newIdentNode("yamlStartMap")), newIdentNode("yamlStartMap")),
newNimNode(nnkExprColonExpr).add(newIdentNode("mapTag"), newNimNode(nnkExprColonExpr).add(newIdentNode("mapTag"),
newNimNode(nnkIfExpr).add(newNimNode(nnkElifExpr).add( newNimNode(nnkIfExpr).add(newNimNode(nnkElifExpr).add(
newNimNode(nnkInfix).add(newIdentNode("=="), newNimNode(nnkInfix).add(newIdentNode("=="),
newIdentNode("tagStyle"), newIdentNode("ytsNone")), newIdentNode("tagStyle"),
newIdentNode("ytsNone")),
newIdentNode("yTagQuestionMark") newIdentNode("yTagQuestionMark")
), newNimNode(nnkElseExpr).add( ), newNimNode(nnkElseExpr).add(
newCall("yamlTag", newCall("type", tIdent)) newCall("yamlTag", newCall("type", tIdent))
@ -145,27 +153,21 @@ macro make_serializable*(types: stmt): stmt =
) )
))) )))
var i = 1 var i = 2
for field in objectFields(recList): for field in objectFields(recList):
let let
fieldIterIdent = newIdentNode($field.name & "Events") fieldIterIdent = newIdentNode($field.name & "Events")
fieldNameString = newStrLitNode($field.name) fieldNameString = newStrLitNode($field.name)
iterbody.insert(i, quote do: iterbody.insert(i, quote do:
yield YamlStreamEvent(kind: yamlScalar, yield YamlStreamEvent(kind: yamlScalar,
scalarTag: presentTag(string), scalarTag: presentTag(string,
childTagStyle),
scalarAnchor: yAnchorNone, scalarAnchor: yAnchorNone,
scalarContent: `fieldNameString`) scalarContent: `fieldNameString`)
) )
iterbody.insert(i + 1, newVarStmt(fieldIterIdent, iterbody.insert(i + 1, newVarStmt(fieldIterIdent,
newCall("serialize", newDotExpr(newIdentNode("value"), newCall("serialize", newDotExpr(newIdentNode("value"),
field.name), newNimNode(nnkIfExpr).add( field.name), newIdentNode("childTagStyle"))))
newNimNode(nnkElifExpr).add(
newNimNode(nnkInfix).add(newIdentNode("=="),
newIdentNode("tagStyle"),
newIdentNode("ytsRootOnly")),
newIdentNode("ytsNone")),
newNimNode(nnkElseExpr).add(
newIdentNode("tagStyle"))))))
iterbody.insert(i + 2, quote do: iterbody.insert(i + 2, quote do:
for event in `fieldIterIdent`(): for event in `fieldIterIdent`():
yield event yield event
@ -196,7 +198,8 @@ proc construct*(s: YamlStream, result: var string) =
proc serialize*(value: string, proc serialize*(value: string,
tagStyle: YamlTagStyle = ytsNone): YamlStream = tagStyle: YamlTagStyle = ytsNone): YamlStream =
result = iterator(): YamlStreamEvent = result = iterator(): YamlStreamEvent =
yield YamlStreamEvent(kind: yamlScalar, scalarTag: presentTag(string), yield YamlStreamEvent(kind: yamlScalar,
scalarTag: presentTag(string, tagStyle),
scalarAnchor: yAnchorNone, scalarContent: value) scalarAnchor: yAnchorNone, scalarContent: value)
proc yamlTag*(T: typedesc[int]): TagId {.inline.} = yTagInteger proc yamlTag*(T: typedesc[int]): TagId {.inline.} = yTagInteger
@ -214,7 +217,7 @@ proc serialize*(value: int,
tagStyle: YamlTagStyle = ytsNone): YamlStream = tagStyle: YamlTagStyle = ytsNone): YamlStream =
result = iterator(): YamlStreamEvent = result = iterator(): YamlStreamEvent =
yield YamlStreamEvent(kind: yamlScalar, yield YamlStreamEvent(kind: yamlScalar,
scalarTag: presentTag(int), scalarTag: presentTag(int, tagStyle),
scalarAnchor: yAnchorNone, scalarContent: $value) scalarAnchor: yAnchorNone, scalarContent: $value)
proc yamlTag*(T: typedesc[int64]): TagId {.inline.} = yTagInteger proc yamlTag*(T: typedesc[int64]): TagId {.inline.} = yTagInteger
@ -231,7 +234,8 @@ proc contruct*(s: YamlStream, result: var int64) =
proc serialize*(value: int64, proc serialize*(value: int64,
tagStyle: YamlTagStyle = ytsNone): YamlStream = tagStyle: YamlTagStyle = ytsNone): YamlStream =
result = iterator(): YamlStreamEvent = result = iterator(): YamlStreamEvent =
yield YamlStreamEvent(kind: yamlScalar, scalarTag: presentTag(int64), yield YamlStreamEvent(kind: yamlScalar,
scalarTag: presentTag(int64, tagStyle),
scalarAnchor: yAnchorNone, scalarContent: $value) scalarAnchor: yAnchorNone, scalarContent: $value)
proc yamlTag*(T: typedesc[float]): TagId {.inline.} = yTagFloat proc yamlTag*(T: typedesc[float]): TagId {.inline.} = yTagFloat
@ -264,7 +268,8 @@ proc serialize*(value: float,
of NaN: ".nan" of NaN: ".nan"
else: $value else: $value
yield YamlStreamEvent(kind: yamlScalar, scalarTag: presentTag(float), yield YamlStreamEvent(kind: yamlScalar,
scalarTag: presentTag(float, tagStyle),
scalarAnchor: yAnchorNone, scalarContent: asString) scalarAnchor: yAnchorNone, scalarContent: asString)
proc yamlTag*(T: typedesc[bool]): TagId {.inline.} = yTagBoolean proc yamlTag*(T: typedesc[bool]): TagId {.inline.} = yTagBoolean
@ -287,7 +292,7 @@ proc serialize*(value: bool,
tagStyle: YamlTagStyle = ytsNone): YamlStream = tagStyle: YamlTagStyle = ytsNone): YamlStream =
result = iterator(): YamlStreamEvent = result = iterator(): YamlStreamEvent =
yield YamlStreamEvent(kind: yamlScalar, yield YamlStreamEvent(kind: yamlScalar,
scalarTag: presentTag(bool), scalarTag: presentTag(bool, tagStyle),
scalarAnchor: yAnchorNone, scalarContent: scalarAnchor: yAnchorNone, scalarContent:
if value: "y" else: "n") if value: "y" else: "n")
@ -323,12 +328,12 @@ proc construct*[T](s: YamlStream, result: var seq[T]) =
proc serialize*[T](value: seq[T], proc serialize*[T](value: seq[T],
tagStyle: YamlTagStyle = ytsNone): YamlStream = tagStyle: YamlTagStyle = ytsNone): YamlStream =
result = iterator(): YamlStreamEvent = result = iterator(): YamlStreamEvent =
let childTagStyle = if tagStyle == ytsRootOnly: ytsNone else: tagStyle
yield YamlStreamEvent(kind: yamlStartSequence, yield YamlStreamEvent(kind: yamlStartSequence,
seqTag: presentTag(seq[T]), seqTag: presentTag(seq[T], tagStyle),
seqAnchor: yAnchorNone) seqAnchor: yAnchorNone)
for item in value: for item in value:
var events = serialize(item, if tagStyle == ytsRootOnly: var events = serialize(item, childTagStyle)
ytsNone else: tagStyle)
for event in events(): for event in events():
yield event yield event
yield YamlStreamEvent(kind: yamlEndSequence) yield YamlStreamEvent(kind: yamlEndSequence)
@ -369,15 +374,15 @@ proc construct*[K, V](s: YamlStream, result: var Table[K, V]) =
proc serialize*[K, V](value: Table[K, V], proc serialize*[K, V](value: Table[K, V],
tagStyle: YamlTagStyle = ytsNone): YamlStream = tagStyle: YamlTagStyle = ytsNone): YamlStream =
result = iterator(): YamlStreamEvent = result = iterator(): YamlStreamEvent =
yield YamlStreamEvent(kind: yamlStartMap, mapTag: yTagQuestionMark, let childTagStyle = if tagStyle == ytsRootOnly: ytsNone else: tagStyle
yield YamlStreamEvent(kind: yamlStartMap,
mapTag: presentTag(Table[K, V], tagStyle),
mapAnchor: yAnchorNone) mapAnchor: yAnchorNone)
for key, value in value.pairs: for key, value in value.pairs:
var events = serialize(key, if tagStyle == ytsRootOnly: var events = serialize(key, childTagStyle)
ytsNone else: tagStyle)
for event in events(): for event in events():
yield event yield event
events = serialize(value, if tagStyle == ytsRootOnly: events = serialize(value, childTagStyle)
ytsNone else: tagStyle)
for event in events(): for event in events():
yield event yield event
yield YamlStreamEvent(kind: yamlEndMap) yield YamlStreamEvent(kind: yamlEndMap)