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 endMapEvent()
|
||||||
yield endSeqEvent()
|
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]):
|
proc yamlTag*(T: typedesc[object|enum]):
|
||||||
TagId {.inline, noSideEffect, raises: [].} =
|
TagId {.inline, raises: [].} =
|
||||||
when compiles(yamlTag(T)): result = yamlTag(T)
|
|
||||||
else:
|
|
||||||
var uri = "!nim:custom:" & (typetraits.name(type(T)))
|
var uri = "!nim:custom:" & (typetraits.name(type(T)))
|
||||||
try: serializationTagLibrary.tags[uri]
|
try: serializationTagLibrary.tags[uri]
|
||||||
except KeyError: serializationTagLibrary.registerUri(uri)
|
except KeyError: serializationTagLibrary.registerUri(uri)
|
||||||
|
|
||||||
proc yamlTag*(T: typedesc[tuple]):
|
proc yamlTag*(T: typedesc[tuple]):
|
||||||
TagId {.inline, noSideEffect, raises: [].} =
|
TagId {.inline, raises: [].} =
|
||||||
var
|
var
|
||||||
i: T
|
i: T
|
||||||
uri = "!nim:tuple("
|
uri = "!nim:tuple("
|
||||||
|
@ -423,6 +429,9 @@ proc constructObject*[O: object|tuple](
|
||||||
raise newException(YamlConstructionError,
|
raise newException(YamlConstructionError,
|
||||||
"Expected field name, got " & $e.kind)
|
"Expected field name, got " & $e.kind)
|
||||||
let name = e.scalarContent
|
let name = e.scalarContent
|
||||||
|
when compiles(implicitVariantObject(O)):
|
||||||
|
discard
|
||||||
|
else:
|
||||||
for fname, value in fieldPairs(result):
|
for fname, value in fieldPairs(result):
|
||||||
if fname == name:
|
if fname == name:
|
||||||
constructChild(s, c, value)
|
constructChild(s, c, value)
|
||||||
|
@ -625,6 +634,11 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext):
|
||||||
yield event
|
yield event
|
||||||
except KeyError: assert false, "Can never happen"
|
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) =
|
proc construct*[T](s: var YamlStream, target: var T) =
|
||||||
var context = newConstructionContext()
|
var context = newConstructionContext()
|
||||||
try:
|
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.}
|
RawYamlStream {.inline.}
|
||||||
## Represents a Nim string. Supports nil strings.
|
## 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,
|
proc representChild*[O](value: O, ts: TagStyle,
|
||||||
c: SerializationContext):
|
c: SerializationContext):
|
||||||
RawYamlStream {.raises: [].} =
|
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