mirror of https://github.com/status-im/NimYAML.git
Removed most of variant-object specific code
* fieldPairs() already handles variant objects fine. decided not to go further along the way of identifying object variants by their discriminants in tag URIs. * variant objects are now supported just like normal objects.
This commit is contained in:
parent
a0c435d6eb
commit
e81da97a17
|
@ -387,16 +387,22 @@ proc representObject*[K, V](value: OrderedTable[K, V], ts: TagStyle,
|
|||
yield endMapEvent()
|
||||
yield endSeqEvent()
|
||||
|
||||
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
|
||||
|
||||
proc yamlTag*(T: typedesc[object|enum]):
|
||||
TagId {.inline, noSideEffect, raises: [].} =
|
||||
when compiles(yamlTag(T)): result = yamlTag(T)
|
||||
else:
|
||||
TagId {.inline, raises: [].} =
|
||||
var uri = "!nim:custom:" & (typetraits.name(type(T)))
|
||||
try: serializationTagLibrary.tags[uri]
|
||||
except KeyError: serializationTagLibrary.registerUri(uri)
|
||||
|
||||
proc yamlTag*(T: typedesc[tuple]):
|
||||
TagId {.inline, noSideEffect, raises: [].} =
|
||||
TagId {.inline, raises: [].} =
|
||||
var
|
||||
i: T
|
||||
uri = "!nim:tuple("
|
||||
|
@ -423,6 +429,9 @@ proc constructObject*[O: object|tuple](
|
|||
raise newException(YamlConstructionError,
|
||||
"Expected field name, got " & $e.kind)
|
||||
let name = e.scalarContent
|
||||
when compiles(implicitVariantObject(O)):
|
||||
discard
|
||||
else:
|
||||
for fname, value in fieldPairs(result):
|
||||
if fname == name:
|
||||
constructChild(s, c, value)
|
||||
|
@ -625,6 +634,11 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext):
|
|||
yield event
|
||||
except KeyError: assert false, "Can never happen"
|
||||
|
||||
proc representChild*[O](value: O, ts: TagStyle,
|
||||
c: SerializationContext): RawYamlStream =
|
||||
result = representObject(value, ts, c, if ts == tsNone:
|
||||
yTagQuestionMark else: yamlTag(O))
|
||||
|
||||
proc construct*[T](s: var YamlStream, target: var T) =
|
||||
var context = newConstructionContext()
|
||||
try:
|
||||
|
|
27
test1.nim
27
test1.nim
|
@ -1,27 +0,0 @@
|
|||
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)
|
49
yaml.nim
49
yaml.nim
|
@ -624,57 +624,10 @@ 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: [].} =
|
||||
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