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()
|
||||
|
||||
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)))
|
||||
try: serializationTagLibrary.tags[uri]
|
||||
except KeyError: serializationTagLibrary.registerUri(uri)
|
||||
|
@ -554,10 +554,6 @@ proc constructChild*[O](s: var YamlStream, c: ConstructionContext,
|
|||
e.parent = getCurrentException()
|
||||
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):
|
||||
RawYamlStream =
|
||||
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
|
||||
## ``SerializationContext``.
|
||||
|
||||
proc representChild*[O](value: O, ts: TagStyle, c: SerializationContext):
|
||||
proc representChild*(value: string, ts: TagStyle, c: SerializationContext):
|
||||
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.
|
||||
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)
|
||||
{.raises: [YamlConstructionError, YamlStreamError].}
|
||||
|
|
Loading…
Reference in New Issue