mirror of https://github.com/status-im/NimYAML.git
Worked on variant objects (not working)
This commit is contained in:
parent
273093e390
commit
f73dfdc6ab
|
@ -385,7 +385,7 @@ proc representObject*[K, V](value: OrderedTable[K, V], ts: TagStyle,
|
||||||
yield endSeqEvent()
|
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(yamlTag(T)): yamlTag(T) else:
|
||||||
"!nim:custom:" & (typetraits.name(type(T)))
|
"!nim:custom:" & (typetraits.name(type(T)))
|
||||||
try: serializationTagLibrary.tags[uri]
|
try: serializationTagLibrary.tags[uri]
|
||||||
except KeyError: serializationTagLibrary.registerUri(uri)
|
except KeyError: serializationTagLibrary.registerUri(uri)
|
||||||
|
@ -554,10 +554,6 @@ proc constructChild*[O](s: var YamlStream, c: ConstructionContext,
|
||||||
e.parent = getCurrentException()
|
e.parent = getCurrentException()
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
proc representChild*[O](value: O, ts: TagStyle, c: SerializationContext):
|
|
||||||
RawYamlStream =
|
|
||||||
result = representObject(value, ts, c, presentTag(O, ts))
|
|
||||||
|
|
||||||
proc representChild*(value: string, ts: TagStyle, c: SerializationContext):
|
proc representChild*(value: string, ts: TagStyle, c: SerializationContext):
|
||||||
RawYamlStream =
|
RawYamlStream =
|
||||||
if isNil(value):
|
if isNil(value):
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import yaml, macros
|
||||||
|
|
||||||
|
type
|
||||||
|
FooKind = enum
|
||||||
|
fooInt, fooBool, fooNone
|
||||||
|
FooKind2 = enum
|
||||||
|
fooAddString, fooAddNone
|
||||||
|
|
||||||
|
Foo = object
|
||||||
|
a: string
|
||||||
|
case b: FooKind
|
||||||
|
of fooInt:
|
||||||
|
c: int32
|
||||||
|
of fooBool:
|
||||||
|
d: bool
|
||||||
|
of fooNone:
|
||||||
|
discard
|
||||||
|
case c2: FooKind2
|
||||||
|
of fooAddString:
|
||||||
|
e: string
|
||||||
|
of fooAddNone:
|
||||||
|
discard
|
||||||
|
|
||||||
|
var o = newFileStream(stdout)
|
||||||
|
var f = Foo(a: "a", b: fooBool, d: true)
|
||||||
|
|
||||||
|
dump(f, o)
|
54
yaml.nim
54
yaml.nim
|
@ -602,9 +602,61 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext):
|
||||||
## may be represented as alias node if it is already present in the
|
## may be represented as alias node if it is already present in the
|
||||||
## ``SerializationContext``.
|
## ``SerializationContext``.
|
||||||
|
|
||||||
proc representChild*[O](value: O, ts: TagStyle, c: SerializationContext):
|
proc representChild*(value: string, ts: TagStyle, c: SerializationContext):
|
||||||
RawYamlStream {.inline.}
|
RawYamlStream {.inline.}
|
||||||
|
## Represents a Nim string. Supports nil strings.
|
||||||
|
|
||||||
|
proc isVariant(t: typedesc): bool {.compileTime.} =
|
||||||
|
let typeDesc = getType(t)
|
||||||
|
if typeDesc.len > 1:
|
||||||
|
for child in typeDesc[1].children:
|
||||||
|
if child.kind == nnkRecCase:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
macro presentTagDiscriminators(target: string, t: typedesc, val: expr): stmt =
|
||||||
|
var first = true
|
||||||
|
let typeDesc = getType(getType(t)[1])
|
||||||
|
for child in typeDesc[1].children:
|
||||||
|
if child.kind != nnkRecCase: continue
|
||||||
|
|
||||||
|
template discriminantToString(): NimNode =
|
||||||
|
newNimNode(nnkInfix).add(
|
||||||
|
newIdentNode("$"), newDotExpr(val, child[0])
|
||||||
|
)
|
||||||
|
|
||||||
|
if first:
|
||||||
|
first = false
|
||||||
|
result = newNimNode(nnkInfix).add(
|
||||||
|
newIdentNode("&"), newStrLitNode("("), discriminantToString()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
result = newNimNode(nnkInfix).add(
|
||||||
|
newIdentNode("&"), result, newNimNode(nnkInfix).add(
|
||||||
|
newIdentNode("&"), newStrLitNode(","), discriminantToString())
|
||||||
|
)
|
||||||
|
if first: # no discriminators
|
||||||
|
result = newNimNode(nnkDiscardStmt).add(newNimNode(nnkEmpty))
|
||||||
|
else:
|
||||||
|
result = newNimNode(nnkInfix).add(newIdentNode("&="), target,
|
||||||
|
newNimNode(nnkInfix).add(newIdentNode("&"), result, newStrLitNode(")")))
|
||||||
|
|
||||||
|
template presentVariantObjectTag[O](t: typedesc[object], val: O): TagId =
|
||||||
|
var oTag = name(t)
|
||||||
|
presentTagDiscriminators(oTag, t, val)
|
||||||
|
try: serializationTagLibrary.tags[oTag]
|
||||||
|
except KeyError: serializationTagLibrary.registerUri(oTag)
|
||||||
|
|
||||||
|
proc representChild*[O](value: O, ts: TagStyle,
|
||||||
|
c: SerializationContext):
|
||||||
|
RawYamlStream {.raises: [].} =
|
||||||
## Represents an arbitrary Nim object as YAML object.
|
## Represents an arbitrary Nim object as YAML object.
|
||||||
|
const isVar = isVariant(O)
|
||||||
|
when isVar:
|
||||||
|
result = representObject(value, ts, c, presentVariantObjectTag(O, value))
|
||||||
|
else:
|
||||||
|
result = representObject(value, ts, c, if ts == tsNone:
|
||||||
|
yTagQuestionMark else: yamlTag(O))
|
||||||
|
|
||||||
proc construct*[T](s: var YamlStream, target: var T)
|
proc construct*[T](s: var YamlStream, target: var T)
|
||||||
{.raises: [YamlConstructionError, YamlStreamError].}
|
{.raises: [YamlConstructionError, YamlStreamError].}
|
||||||
|
|
Loading…
Reference in New Issue