mirror of https://github.com/status-im/NimYAML.git
Implemented serializing ref objects.
This commit is contained in:
parent
cec66cd0a2
commit
96f01385ef
|
@ -126,6 +126,15 @@ proc startItem(target: Stream, style: PresentationStyle, indentation: int,
|
||||||
e.parent = getCurrentException()
|
e.parent = getCurrentException()
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
proc anchorName(a: AnchorId): string {.raises: [].} =
|
||||||
|
result = ""
|
||||||
|
var i = int(a)
|
||||||
|
while i >= 0:
|
||||||
|
let j = i mod 36
|
||||||
|
if j < 26: result.add(char(j + ord('a')))
|
||||||
|
else: result.add(char(j + ord('0') - 26))
|
||||||
|
i -= 36
|
||||||
|
|
||||||
proc writeTagAndAnchor(target: Stream, tag: TagId, tagLib: TagLibrary,
|
proc writeTagAndAnchor(target: Stream, tag: TagId, tagLib: TagLibrary,
|
||||||
anchor: AnchorId) {.raises:[YamlPresenterOutputError].} =
|
anchor: AnchorId) {.raises:[YamlPresenterOutputError].} =
|
||||||
try:
|
try:
|
||||||
|
@ -144,8 +153,7 @@ proc writeTagAndAnchor(target: Stream, tag: TagId, tagLib: TagLibrary,
|
||||||
target.write("> ")
|
target.write("> ")
|
||||||
if anchor != yAnchorNone:
|
if anchor != yAnchorNone:
|
||||||
target.write("&")
|
target.write("&")
|
||||||
# TODO: properly select an anchor
|
target.write(anchorName(anchor))
|
||||||
target.write(cast[byte]('a') + cast[byte](anchor))
|
|
||||||
target.write(' ')
|
target.write(' ')
|
||||||
except:
|
except:
|
||||||
var e = newException(YamlPresenterOutputError, "")
|
var e = newException(YamlPresenterOutputError, "")
|
||||||
|
|
|
@ -1,11 +1,23 @@
|
||||||
import "../yaml"
|
import "../yaml"
|
||||||
import macros, strutils, streams, tables, json, hashes, typetraits
|
import macros, strutils, streams, tables, json, hashes, typetraits, queues
|
||||||
export yaml, streams, tables, json
|
export yaml, streams, tables, json
|
||||||
|
|
||||||
type
|
type
|
||||||
TagStyle* = enum
|
TagStyle* = enum
|
||||||
tsNone, tsRootOnly, tsAll
|
tsNone, tsRootOnly, tsAll
|
||||||
|
|
||||||
|
AnchorStyle* = enum
|
||||||
|
asNone, asTidy, asAlways
|
||||||
|
|
||||||
|
RefNodeData* = object
|
||||||
|
p: pointer
|
||||||
|
count: int
|
||||||
|
anchor: AnchorId
|
||||||
|
|
||||||
|
SerializationContext* = ref object
|
||||||
|
refsList: seq[RefNodeData]
|
||||||
|
style: AnchorStyle
|
||||||
|
|
||||||
const
|
const
|
||||||
yTagNimInt8* = 100.TagId
|
yTagNimInt8* = 100.TagId
|
||||||
yTagNimInt16* = 101.TagId
|
yTagNimInt16* = 101.TagId
|
||||||
|
@ -19,6 +31,16 @@ const
|
||||||
yTagNimFloat64* = 109.TagId
|
yTagNimFloat64* = 109.TagId
|
||||||
yTagNimChar* = 110.TagId
|
yTagNimChar* = 110.TagId
|
||||||
|
|
||||||
|
proc initRefNodeData(p: pointer): RefNodeData =
|
||||||
|
result.p = p
|
||||||
|
result.count = 1
|
||||||
|
result.anchor = yAnchorNone
|
||||||
|
|
||||||
|
proc newSerializationContext(s: AnchorStyle): SerializationContext =
|
||||||
|
new(result)
|
||||||
|
result.refsList = newSeq[RefNodeData]()
|
||||||
|
result.style = s
|
||||||
|
|
||||||
proc initSerializationTagLibrary(): TagLibrary {.raises: [].} =
|
proc initSerializationTagLibrary(): TagLibrary {.raises: [].} =
|
||||||
result = initTagLibrary()
|
result = initTagLibrary()
|
||||||
result.tags["!"] = yTagExclamationMark
|
result.tags["!"] = yTagExclamationMark
|
||||||
|
@ -63,8 +85,8 @@ static:
|
||||||
|
|
||||||
var existingTuples = newSeq[NimNode]()
|
var existingTuples = newSeq[NimNode]()
|
||||||
|
|
||||||
template presentTag(t: typedesc, tagStyle: TagStyle): TagId =
|
template presentTag(t: typedesc, ts: TagStyle): TagId =
|
||||||
if tagStyle == tsNone: yTagQuestionMark else: yamlTag(t)
|
if ts == tsNone: yTagQuestionMark else: yamlTag(t)
|
||||||
|
|
||||||
proc lazyLoadTag*(uri: string): TagId {.inline, raises: [].} =
|
proc lazyLoadTag*(uri: string): TagId {.inline, raises: [].} =
|
||||||
try:
|
try:
|
||||||
|
@ -183,9 +205,10 @@ macro serializable*(types: stmt): stmt =
|
||||||
var serializeProc = newProc(newIdentNode("serializeObject"), [
|
var serializeProc = newProc(newIdentNode("serializeObject"), [
|
||||||
newIdentNode("YamlStream"),
|
newIdentNode("YamlStream"),
|
||||||
newIdentDefs(newIdentNode("value"), tIdent),
|
newIdentDefs(newIdentNode("value"), tIdent),
|
||||||
newIdentDefs(newIdentNode("tagStyle"),
|
newIdentDefs(newIdentNode("ts"),
|
||||||
newIdentNode("TagStyle"),
|
newIdentNode("TagStyle")),
|
||||||
newIdentNode("tsNone"))])
|
newIdentDefs(newIdentNode("c"),
|
||||||
|
newIdentNode("SerializationContext"))])
|
||||||
serializeProc[4] = newNimNode(nnkPragma).add(
|
serializeProc[4] = newNimNode(nnkPragma).add(
|
||||||
newNimNode(nnkExprColonExpr).add(newIdentNode("raises"),
|
newNimNode(nnkExprColonExpr).add(newIdentNode("raises"),
|
||||||
newNimNode(nnkBracket)))
|
newNimNode(nnkBracket)))
|
||||||
|
@ -193,9 +216,9 @@ macro serializable*(types: stmt): stmt =
|
||||||
newLetStmt(newIdentNode("childTagStyle"), newNimNode(nnkIfExpr).add(
|
newLetStmt(newIdentNode("childTagStyle"), newNimNode(nnkIfExpr).add(
|
||||||
newNimNode(nnkElifExpr).add(
|
newNimNode(nnkElifExpr).add(
|
||||||
newNimNode(nnkInfix).add(newIdentNode("=="),
|
newNimNode(nnkInfix).add(newIdentNode("=="),
|
||||||
newIdentNode("tagStyle"), newIdentNode("tsRootOnly")),
|
newIdentNode("ts"), newIdentNode("tsRootOnly")),
|
||||||
newIdentNode("tsNone")
|
newIdentNode("tsNone")
|
||||||
), newNimNode(nnkElseExpr).add(newIdentNode("tagStyle")))),
|
), newNimNode(nnkElseExpr).add(newIdentNode("ts")))),
|
||||||
newNimNode(nnkYieldStmt).add(
|
newNimNode(nnkYieldStmt).add(
|
||||||
newNimNode(nnkObjConstr).add(newIdentNode("YamlStreamEvent"),
|
newNimNode(nnkObjConstr).add(newIdentNode("YamlStreamEvent"),
|
||||||
newNimNode(nnkExprColonExpr).add(newIdentNode("kind"),
|
newNimNode(nnkExprColonExpr).add(newIdentNode("kind"),
|
||||||
|
@ -203,7 +226,7 @@ macro serializable*(types: stmt): stmt =
|
||||||
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("ts"),
|
||||||
newIdentNode("tsNone")),
|
newIdentNode("tsNone")),
|
||||||
newIdentNode("yTagQuestionMark")
|
newIdentNode("yTagQuestionMark")
|
||||||
), newNimNode(nnkElseExpr).add(
|
), newNimNode(nnkElseExpr).add(
|
||||||
|
@ -232,7 +255,8 @@ macro serializable*(types: stmt): stmt =
|
||||||
)
|
)
|
||||||
iterbody.insert(i + 1, newVarStmt(fieldIterIdent,
|
iterbody.insert(i + 1, newVarStmt(fieldIterIdent,
|
||||||
newCall("serializeObject", newDotExpr(newIdentNode("value"),
|
newCall("serializeObject", newDotExpr(newIdentNode("value"),
|
||||||
field.name), newIdentNode("childTagStyle"))))
|
field.name), newIdentNode("childTagStyle"),
|
||||||
|
newIdentNode("c"))))
|
||||||
iterbody.insert(i + 2, quote do:
|
iterbody.insert(i + 2, quote do:
|
||||||
for event in `fieldIterIdent`():
|
for event in `fieldIterIdent`():
|
||||||
yield event
|
yield event
|
||||||
|
@ -299,8 +323,8 @@ proc constructObject*(s: YamlStream, result: var string)
|
||||||
constructScalarItem(item, "string", yTagString):
|
constructScalarItem(item, "string", yTagString):
|
||||||
result = item.scalarContent
|
result = item.scalarContent
|
||||||
|
|
||||||
proc serializeObject*(value: string,
|
proc serializeObject*(value: string, ts: TagStyle = tsNone,
|
||||||
ts: TagStyle = tsNone): YamlStream {.raises: [].} =
|
c: SerializationContext): YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
yield scalarEvent(value, presentTag(string, ts), yAnchorNone)
|
yield scalarEvent(value, presentTag(string, ts), yAnchorNone)
|
||||||
|
|
||||||
|
@ -319,13 +343,14 @@ template constructObject*(s: YamlStream, result: var int) =
|
||||||
{.fatal: "The length of `int` is platform dependent. Use int[8|16|32|64].".}
|
{.fatal: "The length of `int` is platform dependent. Use int[8|16|32|64].".}
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc serializeObject*[T: int8|int16|int32|int64](value: T,
|
proc serializeObject*[T: int8|int16|int32|int64](
|
||||||
ts: TagStyle = tsNone):
|
value: T, ts: TagStyle = tsNone, c: SerializationContext):
|
||||||
YamlStream {.raises: [].} =
|
YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
yield scalarEvent($value, presentTag(T, ts), yAnchorNone)
|
yield scalarEvent($value, presentTag(T, ts), yAnchorNone)
|
||||||
|
|
||||||
template serialize*(value: int, tagStyle: TagStyle = tsNone) =
|
template serializeObject*(value: int, tagStyle: TagStyle,
|
||||||
|
c: SerializationContext) =
|
||||||
{.fatal: "The length of `int` is platform dependent. Use int[8|16|32|64].".}
|
{.fatal: "The length of `int` is platform dependent. Use int[8|16|32|64].".}
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
@ -359,11 +384,12 @@ template constructObject*(s: YamlStream, result: var uint) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc serializeObject*[T: uint8|uint16|uint32|uint64](
|
proc serializeObject*[T: uint8|uint16|uint32|uint64](
|
||||||
value: T, ts: TagStyle = tsNone): YamlStream {.raises: [].} =
|
value: T, ts: TagStyle, c: SerializationContext):
|
||||||
|
YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
yield scalarEvent($value, presentTag(T, ts), yAnchorNone)
|
yield scalarEvent($value, presentTag(T, ts), yAnchorNone)
|
||||||
|
|
||||||
template serializeObject*(value: uint, ts: TagStyle = tsNone) =
|
template serializeObject*(value: uint, ts: TagStyle, c: SerializationContext) =
|
||||||
{.fatal:
|
{.fatal:
|
||||||
"The length of `uint` is platform dependent. Use uint[8|16|32|64].".}
|
"The length of `uint` is platform dependent. Use uint[8|16|32|64].".}
|
||||||
discard
|
discard
|
||||||
|
@ -395,7 +421,8 @@ proc constructObject*[T: float32|float64](s: YamlStream, result: var T)
|
||||||
template constructObject*(s: YamlStream, result: var float) =
|
template constructObject*(s: YamlStream, result: var float) =
|
||||||
{.fatal: "The length of `float` is platform dependent. Use float[32|64].".}
|
{.fatal: "The length of `float` is platform dependent. Use float[32|64].".}
|
||||||
|
|
||||||
proc serializeObject*[T: float32|float64](value: T, ts: TagStyle = tsNone):
|
proc serializeObject*[T: float32|float64](value: T, ts: TagStyle,
|
||||||
|
c: SerializationContext):
|
||||||
YamlStream {.raises: [].} =
|
YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
var
|
var
|
||||||
|
@ -411,7 +438,8 @@ proc serializeObject*[T: float32|float64](value: T, ts: TagStyle = tsNone):
|
||||||
asString = $value
|
asString = $value
|
||||||
yield scalarEvent(asString, presentTag(T, ts), yAnchorNone)
|
yield scalarEvent(asString, presentTag(T, ts), yAnchorNone)
|
||||||
|
|
||||||
template serializeObject*(value: float, tagStyle: TagStyle = tsNone) =
|
template serializeObject*(value: float, tagStyle: TagStyle,
|
||||||
|
c: SerializationContext) =
|
||||||
{.fatal: "The length of `float` is platform dependent. Use float[32|64].".}
|
{.fatal: "The length of `float` is platform dependent. Use float[32|64].".}
|
||||||
|
|
||||||
proc yamlTag*(T: typedesc[bool]): TagId {.inline, raises: [].} = yTagBoolean
|
proc yamlTag*(T: typedesc[bool]): TagId {.inline, raises: [].} = yTagBoolean
|
||||||
|
@ -429,8 +457,8 @@ proc constructObject*(s: YamlStream, result: var bool)
|
||||||
raise newException(YamlConstructionError,
|
raise newException(YamlConstructionError,
|
||||||
"Cannot construct to bool: " & item.scalarContent)
|
"Cannot construct to bool: " & item.scalarContent)
|
||||||
|
|
||||||
proc serializeObject*(value: bool, ts: TagStyle = tsNone): YamlStream
|
proc serializeObject*(value: bool, ts: TagStyle,
|
||||||
{.raises: [].} =
|
c: SerializationContext): YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
yield scalarEvent(if value: "y" else: "n", presentTag(bool, ts),
|
yield scalarEvent(if value: "y" else: "n", presentTag(bool, ts),
|
||||||
yAnchorNone)
|
yAnchorNone)
|
||||||
|
@ -448,8 +476,8 @@ proc constructObject*(s: YamlStream, result: var char)
|
||||||
else:
|
else:
|
||||||
result = item.scalarContent[0]
|
result = item.scalarContent[0]
|
||||||
|
|
||||||
proc serializeObject*(value: char, ts: TagStyle = tsNone): YamlStream
|
proc serializeObject*(value: char, ts: TagStyle,
|
||||||
{.raises: [].} =
|
c: SerializationContext): YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
yield scalarEvent("" & value, presentTag(char, ts), yAnchorNone)
|
yield scalarEvent("" & value, presentTag(char, ts), yAnchorNone)
|
||||||
|
|
||||||
|
@ -482,15 +510,15 @@ proc constructObject*[T](s: YamlStream, result: var seq[T])
|
||||||
safeNextEvent(event, s)
|
safeNextEvent(event, s)
|
||||||
assert(not finished(s))
|
assert(not finished(s))
|
||||||
|
|
||||||
proc serializeObject*[T](value: seq[T], ts: TagStyle = tsNone): YamlStream
|
proc serializeObject*[T](value: seq[T], ts: TagStyle,
|
||||||
{.raises: [].} =
|
c: SerializationContext): YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
yield YamlStreamEvent(kind: yamlStartSequence,
|
yield YamlStreamEvent(kind: yamlStartSequence,
|
||||||
seqTag: presentTag(seq[T], ts),
|
seqTag: presentTag(seq[T], ts),
|
||||||
seqAnchor: yAnchorNone)
|
seqAnchor: yAnchorNone)
|
||||||
for item in value:
|
for item in value:
|
||||||
var events = serializeObject(item, childTagStyle)
|
var events = serializeObject(item, childTagStyle, c)
|
||||||
for event in events():
|
for event in events():
|
||||||
yield event
|
yield event
|
||||||
yield YamlStreamEvent(kind: yamlEndSequence)
|
yield YamlStreamEvent(kind: yamlEndSequence)
|
||||||
|
@ -537,22 +565,82 @@ proc constructObject*[K, V](s: YamlStream, result: var Table[K, V])
|
||||||
safeNextEvent(event, s)
|
safeNextEvent(event, s)
|
||||||
assert(not finished(s))
|
assert(not finished(s))
|
||||||
|
|
||||||
proc serializeObject*[K, V](value: Table[K, V],
|
proc serializeObject*[K, V](value: Table[K, V], ts: TagStyle,
|
||||||
ts: TagStyle = tsNone): YamlStream {.raises: [].} =
|
c: SerializationContext): YamlStream {.raises:[].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
yield YamlStreamEvent(kind: yamlStartMap,
|
yield YamlStreamEvent(kind: yamlStartMap,
|
||||||
mapTag: presentTag(Table[K, V], ts),
|
mapTag: presentTag(Table[K, V], ts),
|
||||||
mapAnchor: yAnchorNone)
|
mapAnchor: yAnchorNone)
|
||||||
for key, value in value.pairs:
|
for key, value in value.pairs:
|
||||||
var events = serializeObject(key, childTagStyle)
|
var events = serializeObject(key, childTagStyle, c)
|
||||||
for event in events():
|
for event in events():
|
||||||
yield event
|
yield event
|
||||||
events = serializeObject(value, childTagStyle)
|
events = serializeObject(value, childTagStyle, c)
|
||||||
for event in events():
|
for event in events():
|
||||||
yield event
|
yield event
|
||||||
yield YamlStreamEvent(kind: yamlEndMap)
|
yield YamlStreamEvent(kind: yamlEndMap)
|
||||||
|
|
||||||
|
proc yamlTag*[O](T: typedesc[ref O]): TagId {.inline, raises: [].} = yamlTag(O)
|
||||||
|
|
||||||
|
proc constructObject*[O](s: YamlStream, result: var ref O)
|
||||||
|
{.raises: [YamlConstructionError, YamlConstructionStreamError].} =
|
||||||
|
var e = s()
|
||||||
|
assert(not finished(s))
|
||||||
|
if e.kind == yamlScalar:
|
||||||
|
if e.scalarTag == yTagNull or (
|
||||||
|
e.scalarTag in [yTagQuestionMark, yTagExclamationMark] and
|
||||||
|
guessType(e.scalarContent) == yTypeNull):
|
||||||
|
result = nil
|
||||||
|
return
|
||||||
|
new(result)
|
||||||
|
try:
|
||||||
|
constructObject(prepend(e, s), result[])
|
||||||
|
except YamlConstructionError, YamlConstructionStreamError:
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
var e = newException(YamlConstructionStreamError,
|
||||||
|
getCurrentExceptionMsg())
|
||||||
|
e.parent = getCurrentException()
|
||||||
|
raise e
|
||||||
|
|
||||||
|
proc serializeObject*[O](value: ref O, ts: TagStyle, c: SerializationContext):
|
||||||
|
YamlStream {.raises: [].} =
|
||||||
|
if value == nil:
|
||||||
|
result = iterator(): YamlStreamEvent = yield scalarEvent("~", yTagNull)
|
||||||
|
elif c.style == asNone:
|
||||||
|
result = serializeObject(value[], ts, c)
|
||||||
|
else:
|
||||||
|
let
|
||||||
|
p = cast[pointer](value)
|
||||||
|
for i in countup(0, c.refsList.high):
|
||||||
|
if p == c.refsList[i].p:
|
||||||
|
c.refsList[i].count.inc()
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
yield aliasEvent(if c.style == asAlways: AnchorId(i) else:
|
||||||
|
cast[AnchorId](p))
|
||||||
|
return
|
||||||
|
c.refsList.add(initRefNodeData(p))
|
||||||
|
let a = if c.style == asAlways: AnchorId(c.refsList.high) else:
|
||||||
|
cast[AnchorId](p)
|
||||||
|
try:
|
||||||
|
var
|
||||||
|
objStream = serializeObject(value[], ts, c)
|
||||||
|
first = objStream()
|
||||||
|
assert(not finished(objStream))
|
||||||
|
case first.kind
|
||||||
|
of yamlStartMap:
|
||||||
|
first.mapAnchor = a
|
||||||
|
of yamlStartSequence:
|
||||||
|
first.seqAnchor = a
|
||||||
|
of yamlScalar:
|
||||||
|
first.scalarAnchor = a
|
||||||
|
else:
|
||||||
|
assert(false)
|
||||||
|
result = prepend(first, objStream)
|
||||||
|
except Exception:
|
||||||
|
assert(false)
|
||||||
|
|
||||||
proc construct*[T](s: YamlStream, target: var T)
|
proc construct*[T](s: YamlStream, target: var T)
|
||||||
{.raises: [YamlConstructionError, YamlConstructionStreamError].} =
|
{.raises: [YamlConstructionError, YamlConstructionStreamError].} =
|
||||||
try:
|
try:
|
||||||
|
@ -591,16 +679,39 @@ proc load*[K](input: Stream, target: var K)
|
||||||
# compiler bug: https://github.com/nim-lang/Nim/issues/3772
|
# compiler bug: https://github.com/nim-lang/Nim/issues/3772
|
||||||
assert(false)
|
assert(false)
|
||||||
|
|
||||||
proc serialize*[T](value: T, ts: TagStyle = tsRootOnly):
|
proc setAnchor(a: var AnchorId, q: var seq[RefNodeData], n: var AnchorId)
|
||||||
YamlStream {.raises: [].} =
|
{.inline.} =
|
||||||
|
if a != yAnchorNone:
|
||||||
|
let p = cast[pointer](a)
|
||||||
|
for i in countup(0, q.len - 1):
|
||||||
|
if p == q[i].p:
|
||||||
|
if q[i].count > 1:
|
||||||
|
assert(q[i].anchor == yAnchorNone)
|
||||||
|
q[i].anchor = n
|
||||||
|
a = n
|
||||||
|
n = AnchorId(int(n) + 1)
|
||||||
|
else:
|
||||||
|
a = yAnchorNone
|
||||||
|
break
|
||||||
|
|
||||||
|
proc setAliasAnchor(a: var AnchorId, q: var seq[RefNodeData]) {.inline.} =
|
||||||
|
let p = cast[pointer](a)
|
||||||
|
for i in countup(0, q.len - 1):
|
||||||
|
if p == q[i].p:
|
||||||
|
assert q[i].count > 1
|
||||||
|
assert q[i].anchor != yAnchorNone
|
||||||
|
a = q[i].anchor
|
||||||
|
return
|
||||||
|
assert(false)
|
||||||
|
|
||||||
|
proc insideDoc(s: YamlStream): YamlStream {.raises: [].} =
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
var serialized = serializeObject(value, ts)
|
|
||||||
yield YamlStreamEvent(kind: yamlStartDocument)
|
yield YamlStreamEvent(kind: yamlStartDocument)
|
||||||
while true:
|
while true:
|
||||||
var event: YamlStreamEvent
|
var event: YamlStreamEvent
|
||||||
try:
|
try:
|
||||||
event = serialized()
|
event = s()
|
||||||
if finished(serialized): break
|
if finished(s): break
|
||||||
except AssertionError: raise
|
except AssertionError: raise
|
||||||
except Exception:
|
except Exception:
|
||||||
# serializing object does not raise any errors, so we can
|
# serializing object does not raise any errors, so we can
|
||||||
|
@ -609,14 +720,54 @@ proc serialize*[T](value: T, ts: TagStyle = tsRootOnly):
|
||||||
yield event
|
yield event
|
||||||
yield YamlStreamEvent(kind: yamlEndDocument)
|
yield YamlStreamEvent(kind: yamlEndDocument)
|
||||||
|
|
||||||
|
proc serialize*[T](value: T, ts: TagStyle = tsRootOnly,
|
||||||
|
a: AnchorStyle = asTidy): YamlStream {.raises: [].} =
|
||||||
|
var
|
||||||
|
context = newSerializationContext(a)
|
||||||
|
objStream: YamlStream
|
||||||
|
try:
|
||||||
|
objStream = insideDoc(serializeObject(value, ts, context))
|
||||||
|
except Exception:
|
||||||
|
assert(false)
|
||||||
|
if a == asTidy:
|
||||||
|
var objQueue = newSeq[YamlStreamEvent]()
|
||||||
|
try:
|
||||||
|
for event in objStream():
|
||||||
|
objQueue.add(event)
|
||||||
|
except Exception:
|
||||||
|
assert(false)
|
||||||
|
var next = 0.AnchorId
|
||||||
|
result = iterator(): YamlStreamEvent =
|
||||||
|
for i in countup(0, objQueue.len - 1):
|
||||||
|
var event = objQueue[i]
|
||||||
|
case event.kind
|
||||||
|
of yamlStartMap:
|
||||||
|
event.mapAnchor.setAnchor(context.refsList, next)
|
||||||
|
of yamlStartSequence:
|
||||||
|
event.seqAnchor.setAnchor(context.refsList, next)
|
||||||
|
of yamlScalar:
|
||||||
|
event.scalarAnchor.setAnchor(context.refsList, next)
|
||||||
|
of yamlAlias:
|
||||||
|
event.aliasTarget.setAliasAnchor(context.refsList)
|
||||||
|
else:
|
||||||
|
discard
|
||||||
|
yield event
|
||||||
|
else:
|
||||||
|
result = objStream
|
||||||
|
|
||||||
proc dump*[K](value: K, target: Stream, style: PresentationStyle = psDefault,
|
proc dump*[K](value: K, target: Stream, style: PresentationStyle = psDefault,
|
||||||
tagStyle: TagStyle = tsRootOnly, indentationStep: int = 2)
|
tagStyle: TagStyle = tsRootOnly,
|
||||||
|
anchorStyle: AnchorStyle = asTidy, indentationStep: int = 2)
|
||||||
{.raises: [YamlPresenterJsonError, YamlPresenterOutputError].} =
|
{.raises: [YamlPresenterJsonError, YamlPresenterOutputError].} =
|
||||||
var events = serialize(value, if style == psCanonical: tsAll else: tagStyle)
|
var events = serialize(value, if style == psCanonical: tsAll else: tagStyle,
|
||||||
|
if style == psJson: asNone else: anchorStyle)
|
||||||
try:
|
try:
|
||||||
present(events, target, serializationTagLibrary, style, indentationStep)
|
present(events, target, serializationTagLibrary, style, indentationStep)
|
||||||
except YamlPresenterStreamError:
|
except YamlPresenterStreamError:
|
||||||
# serializing object does not raise any errors, so we can ignore this
|
# serializing object does not raise any errors, so we can ignore this
|
||||||
|
var e = getCurrentException()
|
||||||
|
echo e.msg
|
||||||
|
echo e.parent.repr
|
||||||
assert(false)
|
assert(false)
|
||||||
except YamlPresenterJsonError, YamlPresenterOutputError, AssertionError:
|
except YamlPresenterJsonError, YamlPresenterOutputError, AssertionError:
|
||||||
raise
|
raise
|
||||||
|
|
Loading…
Reference in New Issue