mirror of https://github.com/status-im/NimYAML.git
changed TagId to Tag. removed JS stuff that wasn't working anyway.
This commit is contained in:
parent
6238104622
commit
aa65c066d5
|
@ -118,7 +118,7 @@ template yieldEvent() {.dirty.} =
|
||||||
yield curEvent
|
yield curEvent
|
||||||
inEvent = false
|
inEvent = false
|
||||||
|
|
||||||
template setTag(t: TagId) {.dirty.} =
|
template setTag(t: Tag) {.dirty.} =
|
||||||
case curEvent.kind
|
case curEvent.kind
|
||||||
of yamlStartSeq: curEvent.seqProperties.tag = t
|
of yamlStartSeq: curEvent.seqProperties.tag = t
|
||||||
of yamlStartMap: curEvent.mapProperties.tag = t
|
of yamlStartMap: curEvent.mapProperties.tag = t
|
||||||
|
@ -133,8 +133,8 @@ template setAnchor(a: Anchor) {.dirty.} =
|
||||||
of yamlAlias: curEvent.aliasTarget = a
|
of yamlAlias: curEvent.aliasTarget = a
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
template curTag(): TagId =
|
template curTag(): Tag =
|
||||||
var foo: TagId
|
var foo: Tag
|
||||||
case curEvent.kind
|
case curEvent.kind
|
||||||
of yamlStartSeq: foo = curEvent.seqProperties.tag
|
of yamlStartSeq: foo = curEvent.seqProperties.tag
|
||||||
of yamlStartMap: foo = curEvent.mapProperties.tag
|
of yamlStartMap: foo = curEvent.mapProperties.tag
|
||||||
|
@ -143,7 +143,7 @@ template curTag(): TagId =
|
||||||
$curEvent.kind & " may not have a tag")
|
$curEvent.kind & " may not have a tag")
|
||||||
foo
|
foo
|
||||||
|
|
||||||
template setCurTag(val: TagId) =
|
template setCurTag(val: Tag) =
|
||||||
case curEvent.kind
|
case curEvent.kind
|
||||||
of yamlStartSeq: curEvent.seqProperties.tag = val
|
of yamlStartSeq: curEvent.seqProperties.tag = val
|
||||||
of yamlStartMap: curEvent.mapProperties.tag = val
|
of yamlStartMap: curEvent.mapProperties.tag = val
|
||||||
|
|
|
@ -71,7 +71,7 @@ setTagUri(BetterInt, "!test:BetterInt")
|
||||||
const yamlDirs = "%YAML 1.2\n%TAG !n! tag:nimyaml.org,2016:\n--- "
|
const yamlDirs = "%YAML 1.2\n%TAG !n! tag:nimyaml.org,2016:\n--- "
|
||||||
|
|
||||||
proc representObject*(value: BetterInt, ts: TagStyle = tsNone,
|
proc representObject*(value: BetterInt, ts: TagStyle = tsNone,
|
||||||
c: SerializationContext, tag: TagId) {.raises: [].} =
|
c: SerializationContext, tag: Tag) {.raises: [].} =
|
||||||
var
|
var
|
||||||
val = $value
|
val = $value
|
||||||
i = val.len - 3
|
i = val.len - 3
|
||||||
|
|
146
yaml/data.nim
146
yaml/data.nim
|
@ -10,17 +10,8 @@ type
|
||||||
## Anchor provides the operator `$` for converting to string, `==` for
|
## Anchor provides the operator `$` for converting to string, `==` for
|
||||||
## comparison, and `hash` for usage in a hashmap.
|
## comparison, and `hash` for usage in a hashmap.
|
||||||
|
|
||||||
TagId* = distinct int ## \
|
Tag* = distinct string ## \
|
||||||
## A ``TagId`` identifies a tag URI, like for example
|
## A ``Tag`` contains an URI, like for example ``"tag:yaml.org,2002:str"``.
|
||||||
## ``"tag:yaml.org,2002:str"``. The URI corresponding to a ``TagId`` can
|
|
||||||
## be queried from the `TagLibrary <#TagLibrary>`_ which was
|
|
||||||
## used to create this ``TagId``; e.g. when you parse a YAML character
|
|
||||||
## stream, the ``TagLibrary`` of the parser is the one which generates
|
|
||||||
## the resulting ``TagId`` s.
|
|
||||||
##
|
|
||||||
## URI strings are mapped to ``TagId`` s for efficiency reasons (you
|
|
||||||
## do not need to compare strings every time) and to be able to
|
|
||||||
## discover unknown tag URIs early in the parsing process.
|
|
||||||
|
|
||||||
ScalarStyle* = enum
|
ScalarStyle* = enum
|
||||||
## Original style of the scalar (for input),
|
## Original style of the scalar (for input),
|
||||||
|
@ -77,7 +68,21 @@ type
|
||||||
|
|
||||||
Mark* = tuple[line, column: Positive]
|
Mark* = tuple[line, column: Positive]
|
||||||
|
|
||||||
Properties* = tuple[anchor: Anchor, tag: TagId]
|
Properties* = tuple[anchor: Anchor, tag: Tag]
|
||||||
|
|
||||||
|
const
|
||||||
|
yamlTagRepositoryPrefix* = "tag:yaml.org,2002:"
|
||||||
|
nimyamlTagRepositoryPrefix* = "tag:nimyaml.org,2016:"
|
||||||
|
|
||||||
|
proc defineTag*(uri: string): Tag =
|
||||||
|
## defines a tag. Use this to optimize away copies of globally defined
|
||||||
|
## Tags.
|
||||||
|
result = uri.Tag
|
||||||
|
#shallow(result.string) # doesn't work at compile-time
|
||||||
|
|
||||||
|
proc defineCoreTag*(name: string): Tag =
|
||||||
|
## defines a tag in YAML's core namespace, ``tag:yaml.org,2002:``
|
||||||
|
result = defineTag(yamlTagRepositoryPrefix & name)
|
||||||
|
|
||||||
const
|
const
|
||||||
yAnchorNone*: Anchor = "".Anchor ## \
|
yAnchorNone*: Anchor = "".Anchor ## \
|
||||||
|
@ -86,61 +91,36 @@ const
|
||||||
defaultMark: Mark = (1.Positive, 1.Positive) ## \
|
defaultMark: Mark = (1.Positive, 1.Positive) ## \
|
||||||
## used for events that are not generated from input.
|
## used for events that are not generated from input.
|
||||||
|
|
||||||
yTagExclamationMark*: TagId = 0.TagId ## ``!`` non-specific tag
|
yTagExclamationMark*: Tag = defineTag("!")
|
||||||
yTagQuestionMark* : TagId = 1.TagId ## ``?`` non-specific tag
|
yTagQuestionMark* : Tag = defineTag("?")
|
||||||
|
|
||||||
# failsafe schema
|
# failsafe schema
|
||||||
|
|
||||||
yTagString* : TagId = 2.TagId ## \
|
yTagString* = defineCoreTag("str")
|
||||||
## `!!str <http://yaml.org/type/str.html >`_ tag
|
yTagSequence* = defineCoreTag("seq")
|
||||||
yTagSequence* : TagId = 3.TagId ## \
|
yTagMapping* = defineCoreTag("map")
|
||||||
## `!!seq <http://yaml.org/type/seq.html>`_ tag
|
|
||||||
yTagMapping* : TagId = 4.TagId ## \
|
|
||||||
## `!!map <http://yaml.org/type/map.html>`_ tag
|
|
||||||
|
|
||||||
# json & core schema
|
# json & core schema
|
||||||
|
|
||||||
yTagNull* : TagId = 5.TagId ## \
|
yTagNull* = defineCoreTag("null")
|
||||||
## `!!null <http://yaml.org/type/null.html>`_ tag
|
yTagBoolean* = defineCoreTag("bool")
|
||||||
yTagBoolean* : TagId = 6.TagId ## \
|
yTagInteger* = defineCoreTag("int")
|
||||||
## `!!bool <http://yaml.org/type/bool.html>`_ tag
|
yTagFloat* = defineCoreTag("float")
|
||||||
yTagInteger* : TagId = 7.TagId ## \
|
|
||||||
## `!!int <http://yaml.org/type/int.html>`_ tag
|
|
||||||
yTagFloat* : TagId = 8.TagId ## \
|
|
||||||
## `!!float <http://yaml.org/type/float.html>`_ tag
|
|
||||||
|
|
||||||
# other language-independent YAML types (from http://yaml.org/type/ )
|
# other language-independent YAML types (from http://yaml.org/type/ )
|
||||||
|
|
||||||
yTagOrderedMap* : TagId = 9.TagId ## \
|
yTagOrderedMap* = defineCoreTag("omap")
|
||||||
## `!!omap <http://yaml.org/type/omap.html>`_ tag
|
yTagPairs* = defineCoreTag("pairs")
|
||||||
yTagPairs* : TagId = 10.TagId ## \
|
yTagSet* = defineCoreTag("set")
|
||||||
## `!!pairs <http://yaml.org/type/pairs.html>`_ tag
|
yTagBinary* = defineCoreTag("binary")
|
||||||
yTagSet* : TagId = 11.TagId ## \
|
yTagMerge* = defineCoreTag("merge")
|
||||||
## `!!set <http://yaml.org/type/set.html>`_ tag
|
yTagTimestamp* = defineCoreTag("timestamp")
|
||||||
yTagBinary* : TagId = 12.TagId ## \
|
yTagValue* = defineCoreTag("value")
|
||||||
## `!!binary <http://yaml.org/type/binary.html>`_ tag
|
yTagYaml* = defineCoreTag("yaml")
|
||||||
yTagMerge* : TagId = 13.TagId ## \
|
|
||||||
## `!!merge <http://yaml.org/type/merge.html>`_ tag
|
|
||||||
yTagTimestamp* : TagId = 14.TagId ## \
|
|
||||||
## `!!timestamp <http://yaml.org/type/timestamp.html>`_ tag
|
|
||||||
yTagValue* : TagId = 15.TagId ## \
|
|
||||||
## `!!value <http://yaml.org/type/value.html>`_ tag
|
|
||||||
yTagYaml* : TagId = 16.TagId ## \
|
|
||||||
## `!!yaml <http://yaml.org/type/yaml.html>`_ tag
|
|
||||||
|
|
||||||
yTagNimField* : TagId = 100.TagId ## \
|
# NimYAML specific tags
|
||||||
## This tag is used in serialization for the name of a field of an
|
|
||||||
## object. It may contain any string scalar that is a valid Nim symbol.
|
|
||||||
|
|
||||||
yFirstStaticTagId* : TagId = 1000.TagId ## \
|
yTagNimField* = defineTag(nimyamlTagRepositoryPrefix & "field")
|
||||||
## The first ``TagId`` assigned by the ``setTagId`` templates.
|
|
||||||
|
|
||||||
yFirstCustomTagId* : TagId = 10000.TagId ## \
|
|
||||||
## The first ``TagId`` which should be assigned to an URI that does not
|
|
||||||
## exist in the ``YamlTagLibrary`` which is used for parsing.
|
|
||||||
|
|
||||||
yamlTagRepositoryPrefix* = "tag:yaml.org,2002:"
|
|
||||||
nimyamlTagRepositoryPrefix* = "tag:nimyaml.org,2016:"
|
|
||||||
|
|
||||||
proc properties*(event: Event): Properties =
|
proc properties*(event: Event): Properties =
|
||||||
## returns the tag of the given event
|
## returns the tag of the given event
|
||||||
|
@ -186,7 +166,7 @@ proc startMapEvent*(style: CollectionStyle, props: Properties,
|
||||||
mapStyle: style)
|
mapStyle: style)
|
||||||
|
|
||||||
proc startMapEvent*(style: CollectionStyle = csAny,
|
proc startMapEvent*(style: CollectionStyle = csAny,
|
||||||
tag: TagId = yTagQuestionMark,
|
tag: Tag = yTagQuestionMark,
|
||||||
anchor: Anchor = yAnchorNone,
|
anchor: Anchor = yAnchorNone,
|
||||||
startPos, endPos: Mark = defaultMark): Event {.inline.} =
|
startPos, endPos: Mark = defaultMark): Event {.inline.} =
|
||||||
return startMapEvent(style, (anchor, tag), startPos, endPos)
|
return startMapEvent(style, (anchor, tag), startPos, endPos)
|
||||||
|
@ -204,7 +184,7 @@ proc startSeqEvent*(style: CollectionStyle,
|
||||||
seqStyle: style)
|
seqStyle: style)
|
||||||
|
|
||||||
proc startSeqEvent*(style: CollectionStyle = csAny,
|
proc startSeqEvent*(style: CollectionStyle = csAny,
|
||||||
tag: TagId = yTagQuestionMark,
|
tag: Tag = yTagQuestionMark,
|
||||||
anchor: Anchor = yAnchorNone,
|
anchor: Anchor = yAnchorNone,
|
||||||
startPos, endPos: Mark = defaultMark): Event {.inline.} =
|
startPos, endPos: Mark = defaultMark): Event {.inline.} =
|
||||||
return startSeqEvent(style, (anchor, tag), startPos, endPos)
|
return startSeqEvent(style, (anchor, tag), startPos, endPos)
|
||||||
|
@ -221,7 +201,7 @@ proc scalarEvent*(content: string, props: Properties,
|
||||||
kind: yamlScalar, scalarProperties: props,
|
kind: yamlScalar, scalarProperties: props,
|
||||||
scalarContent: content, scalarStyle: style)
|
scalarContent: content, scalarStyle: style)
|
||||||
|
|
||||||
proc scalarEvent*(content: string = "", tag: TagId = yTagQuestionMark,
|
proc scalarEvent*(content: string = "", tag: Tag = yTagQuestionMark,
|
||||||
anchor: Anchor = yAnchorNone,
|
anchor: Anchor = yAnchorNone,
|
||||||
style: ScalarStyle = ssAny,
|
style: ScalarStyle = ssAny,
|
||||||
startPos, endPos: Mark = defaultMark): Event {.inline.} =
|
startPos, endPos: Mark = defaultMark): Event {.inline.} =
|
||||||
|
@ -231,34 +211,13 @@ proc aliasEvent*(target: Anchor, startPos, endPos: Mark = defaultMark): Event {.
|
||||||
## creates a new event that represents a YAML alias
|
## creates a new event that represents a YAML alias
|
||||||
result = Event(startPos: startPos, endPos: endPos, kind: yamlAlias, aliasTarget: target)
|
result = Event(startPos: startPos, endPos: endPos, kind: yamlAlias, aliasTarget: target)
|
||||||
|
|
||||||
proc `==`*(left, right: Anchor): bool {.borrow, locks: 0.}
|
proc `==`*(left, right: Anchor): bool {.borrow.}
|
||||||
proc `$`*(id: Anchor): string {.borrow, locks: 0.}
|
proc `$`*(id: Anchor): string {.borrow.}
|
||||||
proc hash*(id: Anchor): Hash {.borrow, locks: 0.}
|
proc hash*(id: Anchor): Hash {.borrow.}
|
||||||
|
|
||||||
proc `==`*(left, right: TagId): bool {.borrow, locks: 0.}
|
proc `==`*(left, right: Tag): bool {.borrow.}
|
||||||
proc hash*(id: TagId): Hash {.borrow, locks: 0.}
|
proc `$`*(tag: Tag): string {.borrow.}
|
||||||
|
proc hash*(tag: Tag): Hash {.borrow.}
|
||||||
proc `$`*(id: TagId): string {.raises: [].} =
|
|
||||||
case id
|
|
||||||
of yTagQuestionMark: "?"
|
|
||||||
of yTagExclamationMark: "!"
|
|
||||||
of yTagString: "!!str"
|
|
||||||
of yTagSequence: "!!seq"
|
|
||||||
of yTagMapping: "!!map"
|
|
||||||
of yTagNull: "!!null"
|
|
||||||
of yTagBoolean: "!!bool"
|
|
||||||
of yTagInteger: "!!int"
|
|
||||||
of yTagFloat: "!!float"
|
|
||||||
of yTagOrderedMap: "!!omap"
|
|
||||||
of yTagPairs: "!!pairs"
|
|
||||||
of yTagSet: "!!set"
|
|
||||||
of yTagBinary: "!!binary"
|
|
||||||
of yTagMerge: "!!merge"
|
|
||||||
of yTagTimestamp: "!!timestamp"
|
|
||||||
of yTagValue: "!!value"
|
|
||||||
of yTagYaml: "!!yaml"
|
|
||||||
of yTagNimField: "!nim:field"
|
|
||||||
else: "<" & $int(id) & ">"
|
|
||||||
|
|
||||||
proc `==`*(left: Event, right: Event): bool {.raises: [].} =
|
proc `==`*(left: Event, right: Event): bool {.raises: [].} =
|
||||||
## compares all existing fields of the given items
|
## compares all existing fields of the given items
|
||||||
|
@ -279,8 +238,8 @@ proc renderAttrs*(props: Properties, isPlain: bool = true): string =
|
||||||
result = ""
|
result = ""
|
||||||
if props.anchor != yAnchorNone: result &= " &" & $props.anchor
|
if props.anchor != yAnchorNone: result &= " &" & $props.anchor
|
||||||
case props.tag
|
case props.tag
|
||||||
of yTagQuestionmark: discard
|
of yTagQuestionMark: discard
|
||||||
of yTagExclamationmark:
|
of yTagExclamationMark:
|
||||||
if isPlain: result &= " <!>"
|
if isPlain: result &= " <!>"
|
||||||
else:
|
else:
|
||||||
result &= " <" & $props.tag & ">"
|
result &= " <" & $props.tag & ">"
|
||||||
|
@ -313,3 +272,14 @@ proc `$`*(event: Event): string {.raises: [].} =
|
||||||
of ssFolded: result &= " >"
|
of ssFolded: result &= " >"
|
||||||
result &= yamlTestSuiteEscape(event.scalarContent)
|
result &= yamlTestSuiteEscape(event.scalarContent)
|
||||||
of yamlAlias: result = "=ALI *" & $event.aliasTarget
|
of yamlAlias: result = "=ALI *" & $event.aliasTarget
|
||||||
|
|
||||||
|
type
|
||||||
|
TypeID* = int ## unique ID of a type
|
||||||
|
|
||||||
|
var nextTypeID {.compileTime.}: TypeID
|
||||||
|
|
||||||
|
proc typeID*(T:typedesc): TypeID =
|
||||||
|
const id = nextTypeID
|
||||||
|
static:
|
||||||
|
inc nextTypeID
|
||||||
|
return id
|
68
yaml/dom.nim
68
yaml/dom.nim
|
@ -137,11 +137,8 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
||||||
YamlNode {.raises: [YamlStreamError, YamlConstructionError].} =
|
YamlNode {.raises: [YamlStreamError, YamlConstructionError].} =
|
||||||
template addAnchor(c: ConstructionContext, target: Anchor) =
|
template addAnchor(c: ConstructionContext, target: Anchor) =
|
||||||
if target != yAnchorNone:
|
if target != yAnchorNone:
|
||||||
when defined(JS):
|
|
||||||
{.emit: [c, """.refs.set(""", target, ", ", result, ");"].}
|
|
||||||
else:
|
|
||||||
yAssert(not c.refs.hasKey(target))
|
yAssert(not c.refs.hasKey(target))
|
||||||
c.refs[target] = cast[pointer](result)
|
c.refs[target] = (id: typeID(YamlNode), p: cast[pointer](result))
|
||||||
|
|
||||||
var start: Event
|
var start: Event
|
||||||
shallowCopy(start, s.next())
|
shallowCopy(start, s.next())
|
||||||
|
@ -149,7 +146,7 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
||||||
try:
|
try:
|
||||||
case start.kind
|
case start.kind
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
result = YamlNode(tag: tagLib.uri(start.mapProperties.tag),
|
result = YamlNode(tag: $start.mapProperties.tag,
|
||||||
kind: yMapping,
|
kind: yMapping,
|
||||||
fields: newTable[YamlNode, YamlNode]())
|
fields: newTable[YamlNode, YamlNode]())
|
||||||
while s.peek().kind != yamlEndMap:
|
while s.peek().kind != yamlEndMap:
|
||||||
|
@ -162,7 +159,7 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
||||||
discard s.next()
|
discard s.next()
|
||||||
addAnchor(c, start.mapProperties.anchor)
|
addAnchor(c, start.mapProperties.anchor)
|
||||||
of yamlStartSeq:
|
of yamlStartSeq:
|
||||||
result = YamlNode(tag: tagLib.uri(start.seqProperties.tag),
|
result = YamlNode(tag: $start.seqProperties.tag,
|
||||||
kind: ySequence,
|
kind: ySequence,
|
||||||
elems: newSeq[YamlNode]())
|
elems: newSeq[YamlNode]())
|
||||||
while s.peek().kind != yamlEndSeq:
|
while s.peek().kind != yamlEndSeq:
|
||||||
|
@ -170,15 +167,12 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
||||||
addAnchor(c, start.seqProperties.anchor)
|
addAnchor(c, start.seqProperties.anchor)
|
||||||
discard s.next()
|
discard s.next()
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
result = YamlNode(tag: tagLib.uri(start.scalarProperties.tag),
|
result = YamlNode(tag: $start.scalarProperties.tag,
|
||||||
kind: yScalar)
|
kind: yScalar)
|
||||||
shallowCopy(result.content, start.scalarContent)
|
shallowCopy(result.content, start.scalarContent)
|
||||||
addAnchor(c, start.scalarProperties.anchor)
|
addAnchor(c, start.scalarProperties.anchor)
|
||||||
of yamlAlias:
|
of yamlAlias:
|
||||||
when defined(JS):
|
result = cast[YamlNode](c.refs[start.aliasTarget].p)
|
||||||
{.emit: [result, " = ", c, ".refs.get(", start.aliasTarget, ");"].}
|
|
||||||
else:
|
|
||||||
result = cast[YamlNode](c.refs[start.aliasTarget])
|
|
||||||
else: internalError("Malformed YamlStream")
|
else: internalError("Malformed YamlStream")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise newException(YamlConstructionError,
|
raise newException(YamlConstructionError,
|
||||||
|
@ -213,44 +207,22 @@ proc loadDom*(s: Stream | string): YamlDocument
|
||||||
proc serializeNode(n: YamlNode, c: SerializationContext, a: AnchorStyle,
|
proc serializeNode(n: YamlNode, c: SerializationContext, a: AnchorStyle,
|
||||||
tagLib: TagLibrary) {.raises: [].}=
|
tagLib: TagLibrary) {.raises: [].}=
|
||||||
var val = yAnchorNone
|
var val = yAnchorNone
|
||||||
when defined(JS):
|
|
||||||
{.emit: ["""
|
|
||||||
if (""", a, " != ", asNone, " && ", c, ".refs.has(", n, """) {
|
|
||||||
""", val, " = ", c, ".refs.get(", n, """);
|
|
||||||
if (""", c, ".refs.get(", n, ") == ", yAnchorNone, ") {"].}
|
|
||||||
val = c.nextAnchorId
|
|
||||||
{.emit: [c, """.refs.set(""", n, """, """, val, """);"""].}
|
|
||||||
c.nextAnchorId = AnchorId(int(c.nextAnchorId) + 1)
|
|
||||||
{.emit: "}".}
|
|
||||||
c.put(aliasEvent(val))
|
|
||||||
return
|
|
||||||
{.emit: "}".}
|
|
||||||
else:
|
|
||||||
let p = cast[pointer](n)
|
let p = cast[pointer](n)
|
||||||
if a != asNone and c.refs.hasKey(p):
|
if a != asNone and c.refs.hasKey(p):
|
||||||
val = c.refs.getOrDefault(p)
|
val = c.refs.getOrDefault(p).a
|
||||||
if val == yAnchorNone:
|
if val == yAnchorNone:
|
||||||
val = c.nextAnchorId.Anchor
|
val = c.nextAnchorId.Anchor
|
||||||
c.refs[p] = val
|
c.refs[p] = (val, false)
|
||||||
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
||||||
c.put(aliasEvent(val))
|
c.put(aliasEvent(val))
|
||||||
return
|
return
|
||||||
var
|
var
|
||||||
tagId: TagId
|
|
||||||
anchor: Anchor
|
anchor: Anchor
|
||||||
if a == asAlways:
|
if a != asNone:
|
||||||
val = c.nextAnchorId.Anchor
|
val = c.nextAnchorId.Anchor
|
||||||
when defined(JS):
|
c.refs[p] = (c.nextAnchorId.Anchor, false)
|
||||||
{.emit: [c, ".refs.set(", n, ", ", val, ");"].}
|
|
||||||
else:
|
|
||||||
c.refs[p] = c.nextAnchorId.Anchor
|
|
||||||
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
||||||
else:
|
let tag = if tagLib.tags.hasKey(n.tag): tagLib.tags.getOrDefault(n.tag) else:
|
||||||
when defined(JS):
|
|
||||||
{.emit: [c, ".refs.set(", n, ", ", yAnchorNone, ");"].}
|
|
||||||
else:
|
|
||||||
c.refs[p] = yAnchorNone
|
|
||||||
tagId = if tagLib.tags.hasKey(n.tag): tagLib.tags.getOrDefault(n.tag) else:
|
|
||||||
tagLib.registerUri(n.tag)
|
tagLib.registerUri(n.tag)
|
||||||
case a
|
case a
|
||||||
of asNone: anchor = yAnchorNone
|
of asNone: anchor = yAnchorNone
|
||||||
|
@ -258,27 +230,25 @@ proc serializeNode(n: YamlNode, c: SerializationContext, a: AnchorStyle,
|
||||||
of asAlways: anchor = val
|
of asAlways: anchor = val
|
||||||
|
|
||||||
case n.kind
|
case n.kind
|
||||||
of yScalar: c.put(scalarEvent(n.content, tagId, anchor))
|
of yScalar: c.put(scalarEvent(n.content, tag, anchor))
|
||||||
of ySequence:
|
of ySequence:
|
||||||
c.put(startSeqEvent(csBlock, (anchor, tagId)))
|
c.put(startSeqEvent(csBlock, (anchor, tag)))
|
||||||
for item in n.elems:
|
for item in n.elems:
|
||||||
serializeNode(item, c, a, tagLib)
|
serializeNode(item, c, a, tagLib)
|
||||||
c.put(endSeqEvent())
|
c.put(endSeqEvent())
|
||||||
of yMapping:
|
of yMapping:
|
||||||
c.put(startMapEvent(csBlock, (anchor, tagId)))
|
c.put(startMapEvent(csBlock, (anchor, tag)))
|
||||||
for key, value in n.fields.pairs:
|
for key, value in n.fields.pairs:
|
||||||
serializeNode(key, c, a, tagLib)
|
serializeNode(key, c, a, tagLib)
|
||||||
serializeNode(value, c, a, tagLib)
|
serializeNode(value, c, a, tagLib)
|
||||||
c.put(endMapEvent())
|
c.put(endMapEvent())
|
||||||
|
|
||||||
template processAnchoredEvent(target: untyped, c: SerializationContext) =
|
proc processAnchoredEvent(target: var Properties, c: SerializationContext) =
|
||||||
var anchorId: Anchor
|
for key, val in c.refs:
|
||||||
when defined(JS):
|
if val.a == target.anchor:
|
||||||
{.emit: [anchorId, " = ", c, ".refs.get(", target, ");"].}
|
if not val.referenced:
|
||||||
else:
|
target.anchor = yAnchorNone
|
||||||
anchorId = c.refs.getOrDefault(cast[pointer](target.anchor))
|
break
|
||||||
if anchorId != yAnchorNone: target.anchor = anchorId
|
|
||||||
else: target.anchor = yAnchorNone
|
|
||||||
|
|
||||||
proc serialize*(doc: YamlDocument, tagLib: TagLibrary, a: AnchorStyle = asTidy):
|
proc serialize*(doc: YamlDocument, tagLib: TagLibrary, a: AnchorStyle = asTidy):
|
||||||
YamlStream {.raises: [].} =
|
YamlStream {.raises: [].} =
|
||||||
|
|
|
@ -212,7 +212,7 @@ proc generateError(c: Context, message: string):
|
||||||
msg: message, parent: nil, mark: c.lex.curStartPos,
|
msg: message, parent: nil, mark: c.lex.curStartPos,
|
||||||
lineContent: c.lex.currentLine())
|
lineContent: c.lex.currentLine())
|
||||||
|
|
||||||
proc parseTag(c: Context): TagId =
|
proc parseTag(c: Context): Tag =
|
||||||
let handle = c.lex.fullLexeme()
|
let handle = c.lex.fullLexeme()
|
||||||
var uri = c.resolveHandle(handle)
|
var uri = c.resolveHandle(handle)
|
||||||
if uri == "":
|
if uri == "":
|
||||||
|
@ -792,7 +792,7 @@ proc beforeBlockIndentation(c: Context, e: var Event): bool =
|
||||||
elif c.levels[^1].state == beforeBlockIndentation:
|
elif c.levels[^1].state == beforeBlockIndentation:
|
||||||
raise c.generateError("Unexpected double beforeBlockIndentation")
|
raise c.generateError("Unexpected double beforeBlockIndentation")
|
||||||
else:
|
else:
|
||||||
raise c.generateError("Internal error (please report this bug)")
|
raise c.generateError("Internal error (please report this bug): unexpected state at endBlockNode")
|
||||||
c.popLevel()
|
c.popLevel()
|
||||||
c.popLevel()
|
c.popLevel()
|
||||||
case c.lex.cur
|
case c.lex.cur
|
||||||
|
|
|
@ -428,7 +428,7 @@ proc writeTagAndAnchor(c: Context, props: Properties) {.raises: [YamlPresenterOu
|
||||||
let t = c.target
|
let t = c.target
|
||||||
try:
|
try:
|
||||||
if props.tag notin [yTagQuestionMark, yTagExclamationMark]:
|
if props.tag notin [yTagQuestionMark, yTagExclamationMark]:
|
||||||
let tagUri = c.tagLib.uri(props.tag)
|
let tagUri = $props.tag
|
||||||
let (handle, length) = c.searchHandle(tagUri)
|
let (handle, length) = c.searchHandle(tagUri)
|
||||||
if length > 0:
|
if length > 0:
|
||||||
t.append(handle)
|
t.append(handle)
|
||||||
|
|
|
@ -25,16 +25,14 @@ export data, stream, macros, annotations, options
|
||||||
type
|
type
|
||||||
SerializationContext* = ref object
|
SerializationContext* = ref object
|
||||||
## Context information for the process of serializing YAML from Nim values.
|
## Context information for the process of serializing YAML from Nim values.
|
||||||
when not defined(JS):
|
refs*: Table[pointer, tuple[a: Anchor, referenced: bool]]
|
||||||
refs*: Table[pointer, Anchor] # `pointer` does not work with JS
|
|
||||||
style: AnchorStyle
|
style: AnchorStyle
|
||||||
nextAnchorId*: string
|
nextAnchorId*: string
|
||||||
put*: proc(e: Event) {.raises: [], closure.}
|
put*: proc(e: Event) {.raises: [], closure.}
|
||||||
|
|
||||||
ConstructionContext* = ref object
|
ConstructionContext* = ref object
|
||||||
## Context information for the process of constructing Nim values from YAML.
|
## Context information for the process of constructing Nim values from YAML.
|
||||||
when not defined(JS):
|
refs*: Table[Anchor, tuple[id: TypeID, p: pointer]]
|
||||||
refs*: Table[Anchor, pointer]
|
|
||||||
|
|
||||||
YamlConstructionError* = object of YamlLoadingError
|
YamlConstructionError* = object of YamlLoadingError
|
||||||
## Exception that may be raised when constructing data objects from a
|
## Exception that may be raised when constructing data objects from a
|
||||||
|
@ -88,42 +86,35 @@ proc representChild*[O](value: O, ts: TagStyle, c: SerializationContext)
|
||||||
|
|
||||||
proc newConstructionContext*(): ConstructionContext =
|
proc newConstructionContext*(): ConstructionContext =
|
||||||
new(result)
|
new(result)
|
||||||
when defined(JS):
|
result.refs = initTable[Anchor, tuple[id: TypeID, p: pointer]]()
|
||||||
{.emit: [result, """.refs = new Map();"""].}
|
|
||||||
else:
|
|
||||||
result.refs = initTable[Anchor, pointer]()
|
|
||||||
|
|
||||||
proc newSerializationContext*(s: AnchorStyle,
|
proc newSerializationContext*(s: AnchorStyle,
|
||||||
putImpl: proc(e: Event) {.raises: [], closure.}):
|
putImpl: proc(e: Event) {.raises: [], closure.}):
|
||||||
SerializationContext =
|
SerializationContext =
|
||||||
result = SerializationContext(style: s, nextAnchorId: "a",
|
result = SerializationContext(style: s, nextAnchorId: "a",
|
||||||
put: putImpl)
|
put: putImpl)
|
||||||
when defined(JS):
|
result.refs = initTable[pointer, tuple[a: Anchor, referenced: bool]]()
|
||||||
{.emit: [result, """.refs = new Map();"""].}
|
|
||||||
else: result.refs = initTable[pointer, Anchor]()
|
|
||||||
|
|
||||||
template presentTag*(t: typedesc, ts: TagStyle): TagId =
|
template presentTag*(t: typedesc, ts: TagStyle): Tag =
|
||||||
## Get the TagId that represents the given type in the given style
|
## Get the Tag that represents the given type in the given style
|
||||||
if ts == tsNone: yTagQuestionMark else: yamlTag(t)
|
if ts == tsNone: yTagQuestionMark else: yamlTag(t)
|
||||||
|
|
||||||
proc lazyLoadTag(uri: string): TagId {.inline, raises: [].} =
|
proc lazyLoadTag(uri: string): Tag {.inline, raises: [].} =
|
||||||
try: result = serializationTagLibrary.tags[uri]
|
try: result = serializationTagLibrary.tags[uri]
|
||||||
except KeyError: result = serializationTagLibrary.registerUri(uri)
|
except KeyError: result = serializationTagLibrary.registerUri(uri)
|
||||||
|
|
||||||
proc safeTagUri(id: TagId): string {.raises: [].} =
|
proc safeTagUri(tag: Tag): string {.raises: [].} =
|
||||||
try:
|
try:
|
||||||
var
|
var uri = $tag
|
||||||
uri = serializationTagLibrary.uri(id)
|
|
||||||
i = 0
|
|
||||||
# '!' is not allowed inside a tag handle
|
# '!' is not allowed inside a tag handle
|
||||||
if uri.len > 0 and uri[0] == '!': uri = uri[1..^1]
|
if uri.len > 0 and uri[0] == '!': uri = uri[1..^1]
|
||||||
# ',' is not allowed after a tag handle in the suffix because it's a flow
|
# ',' is not allowed after a tag handle in the suffix because it's a flow
|
||||||
# indicator
|
# indicator
|
||||||
for c in uri.mitems():
|
for i in countup(0, uri.len - 1):
|
||||||
if c == ',': c = ';'
|
if uri[i] == ',': uri[i] = ';'
|
||||||
inc(i)
|
|
||||||
return uri
|
return uri
|
||||||
except KeyError: internalError("Unexpected KeyError for TagId " & $id)
|
except KeyError:
|
||||||
|
internalError("Unexpected KeyError for Tag " & $tag)
|
||||||
|
|
||||||
proc constructionError(s: YamlStream, mark: Mark, msg: string): ref YamlConstructionError =
|
proc constructionError(s: YamlStream, mark: Mark, msg: string): ref YamlConstructionError =
|
||||||
result = newException(YamlConstructionError, msg)
|
result = newException(YamlConstructionError, msg)
|
||||||
|
@ -151,7 +142,7 @@ template constructScalarItem*(s: var YamlStream, i: untyped,
|
||||||
e.parent = getCurrentException()
|
e.parent = getCurrentException()
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
proc yamlTag*(T: typedesc[string]): TagId {.inline, noSideEffect, raises: [].} =
|
proc yamlTag*(T: typedesc[string]): Tag {.inline, noSideEffect, raises: [].} =
|
||||||
yTagString
|
yTagString
|
||||||
|
|
||||||
proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
|
@ -162,7 +153,7 @@ proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
result = item.scalarContent
|
result = item.scalarContent
|
||||||
|
|
||||||
proc representObject*(value: string, ts: TagStyle,
|
proc representObject*(value: string, ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) {.raises: [].} =
|
c: SerializationContext, tag: Tag) {.raises: [].} =
|
||||||
## represents a string as YAML scalar
|
## represents a string as YAML scalar
|
||||||
c.put(scalarEvent(value, tag, yAnchorNone))
|
c.put(scalarEvent(value, tag, yAnchorNone))
|
||||||
|
|
||||||
|
@ -217,12 +208,12 @@ proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
result = int(i32Result)
|
result = int(i32Result)
|
||||||
|
|
||||||
proc representObject*[T: int8|int16|int32|int64](value: T, ts: TagStyle,
|
proc representObject*[T: int8|int16|int32|int64](value: T, ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) {.raises: [].} =
|
c: SerializationContext, tag: Tag) {.raises: [].} =
|
||||||
## represents an integer value as YAML scalar
|
## represents an integer value as YAML scalar
|
||||||
c.put(scalarEvent($value, tag, yAnchorNone))
|
c.put(scalarEvent($value, tag, yAnchorNone))
|
||||||
|
|
||||||
proc representObject*(value: int, tagStyle: TagStyle,
|
proc representObject*(value: int, tagStyle: TagStyle,
|
||||||
c: SerializationContext, tag: TagId)
|
c: SerializationContext, tag: Tag)
|
||||||
{.raises: [YamlStreamError], inline.}=
|
{.raises: [YamlStreamError], inline.}=
|
||||||
## represent an integer of architecture-defined length by casting it to int32.
|
## represent an integer of architecture-defined length by casting it to int32.
|
||||||
## on 64-bit systems, this may cause a RangeDefect.
|
## on 64-bit systems, this may cause a RangeDefect.
|
||||||
|
@ -265,12 +256,12 @@ when defined(JS):
|
||||||
result = $BiggestInt(x)
|
result = $BiggestInt(x)
|
||||||
|
|
||||||
proc representObject*[T: uint8|uint16|uint32|uint64](value: T, ts: TagStyle,
|
proc representObject*[T: uint8|uint16|uint32|uint64](value: T, ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) {.raises: [].} =
|
c: SerializationContext, tag: Tag) {.raises: [].} =
|
||||||
## represents an unsigned integer value as YAML scalar
|
## represents an unsigned integer value as YAML scalar
|
||||||
c.put(scalarEvent($value, tag, yAnchorNone))
|
c.put(scalarEvent($value, tag, yAnchorNone))
|
||||||
|
|
||||||
proc representObject*(value: uint, ts: TagStyle, c: SerializationContext,
|
proc representObject*(value: uint, ts: TagStyle, c: SerializationContext,
|
||||||
tag: TagId) {.raises: [YamlStreamError], inline.} =
|
tag: Tag) {.raises: [YamlStreamError], inline.} =
|
||||||
## represent an unsigned integer of architecture-defined length by casting it
|
## represent an unsigned integer of architecture-defined length by casting it
|
||||||
## to int32. on 64-bit systems, this may cause a RangeDefect.
|
## to int32. on 64-bit systems, this may cause a RangeDefect.
|
||||||
try: c.put(scalarEvent($uint32(value), tag, yAnchorNone))
|
try: c.put(scalarEvent($uint32(value), tag, yAnchorNone))
|
||||||
|
@ -299,7 +290,7 @@ proc constructObject*[T: float|float32|float64](
|
||||||
escape(item.scalarContent))
|
escape(item.scalarContent))
|
||||||
|
|
||||||
proc representObject*[T: float|float32|float64](value: T, ts: TagStyle,
|
proc representObject*[T: float|float32|float64](value: T, ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) {.raises: [].} =
|
c: SerializationContext, tag: Tag) {.raises: [].} =
|
||||||
## represents a float value as YAML scalar
|
## represents a float value as YAML scalar
|
||||||
case value
|
case value
|
||||||
of Inf: c.put(scalarEvent(".inf", tag))
|
of Inf: c.put(scalarEvent(".inf", tag))
|
||||||
|
@ -307,7 +298,7 @@ proc representObject*[T: float|float32|float64](value: T, ts: TagStyle,
|
||||||
of NaN: c.put(scalarEvent(".nan", tag))
|
of NaN: c.put(scalarEvent(".nan", tag))
|
||||||
else: c.put(scalarEvent($value, tag))
|
else: c.put(scalarEvent($value, tag))
|
||||||
|
|
||||||
proc yamlTag*(T: typedesc[bool]): TagId {.inline, raises: [].} = yTagBoolean
|
proc yamlTag*(T: typedesc[bool]): Tag {.inline, raises: [].} = yTagBoolean
|
||||||
|
|
||||||
proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
result: var bool)
|
result: var bool)
|
||||||
|
@ -322,7 +313,7 @@ proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
escape(item.scalarContent))
|
escape(item.scalarContent))
|
||||||
|
|
||||||
proc representObject*(value: bool, ts: TagStyle, c: SerializationContext,
|
proc representObject*(value: bool, ts: TagStyle, c: SerializationContext,
|
||||||
tag: TagId) {.raises: [].} =
|
tag: Tag) {.raises: [].} =
|
||||||
## represents a bool value as a YAML scalar
|
## represents a bool value as a YAML scalar
|
||||||
c.put(scalarEvent(if value: "y" else: "n", tag, yAnchorNone))
|
c.put(scalarEvent(if value: "y" else: "n", tag, yAnchorNone))
|
||||||
|
|
||||||
|
@ -337,11 +328,11 @@ proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
else: result = item.scalarContent[0]
|
else: result = item.scalarContent[0]
|
||||||
|
|
||||||
proc representObject*(value: char, ts: TagStyle, c: SerializationContext,
|
proc representObject*(value: char, ts: TagStyle, c: SerializationContext,
|
||||||
tag: TagId) {.raises: [].} =
|
tag: Tag) {.raises: [].} =
|
||||||
## represents a char value as YAML scalar
|
## represents a char value as YAML scalar
|
||||||
c.put(scalarEvent("" & value, tag, yAnchorNone))
|
c.put(scalarEvent("" & value, tag, yAnchorNone))
|
||||||
|
|
||||||
proc yamlTag*(T: typedesc[Time]): TagId {.inline, raises: [].} = yTagTimestamp
|
proc yamlTag*(T: typedesc[Time]): Tag {.inline, raises: [].} = yTagTimestamp
|
||||||
|
|
||||||
proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
result: var Time)
|
result: var Time)
|
||||||
|
@ -403,15 +394,15 @@ proc constructObject*(s: var YamlStream, c: ConstructionContext,
|
||||||
escape(item.scalarContent))
|
escape(item.scalarContent))
|
||||||
|
|
||||||
proc representObject*(value: Time, ts: TagStyle, c: SerializationContext,
|
proc representObject*(value: Time, ts: TagStyle, c: SerializationContext,
|
||||||
tag: TagId) {.raises: [ValueError].} =
|
tag: Tag) {.raises: [ValueError].} =
|
||||||
let tmp = value.utc()
|
let tmp = value.utc()
|
||||||
c.put(scalarEvent(tmp.format("yyyy-MM-dd'T'HH:mm:ss'Z'")))
|
c.put(scalarEvent(tmp.format("yyyy-MM-dd'T'HH:mm:ss'Z'")))
|
||||||
|
|
||||||
proc yamlTag*[I](T: typedesc[seq[I]]): TagId {.inline, raises: [].} =
|
proc yamlTag*[I](T: typedesc[seq[I]]): Tag {.inline, raises: [].} =
|
||||||
let uri = nimTag("system:seq(" & safeTagUri(yamlTag(I)) & ')')
|
let uri = nimTag("system:seq(" & safeTagUri(yamlTag(I)) & ')')
|
||||||
result = lazyLoadTag(uri)
|
result = lazyLoadTag(uri)
|
||||||
|
|
||||||
proc yamlTag*[I](T: typedesc[set[I]]): TagId {.inline, raises: [].} =
|
proc yamlTag*[I](T: typedesc[set[I]]): Tag {.inline, raises: [].} =
|
||||||
let uri = nimTag("system:set(" & safeTagUri(yamlTag(I)) & ')')
|
let uri = nimTag("system:set(" & safeTagUri(yamlTag(I)) & ')')
|
||||||
result = lazyLoadTag(uri)
|
result = lazyLoadTag(uri)
|
||||||
|
|
||||||
|
@ -444,7 +435,7 @@ proc constructObject*[T](s: var YamlStream, c: ConstructionContext,
|
||||||
discard s.next()
|
discard s.next()
|
||||||
|
|
||||||
proc representObject*[T](value: seq[T]|set[T], ts: TagStyle,
|
proc representObject*[T](value: seq[T]|set[T], ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) =
|
c: SerializationContext, tag: Tag) =
|
||||||
## represents a Nim seq as YAML sequence
|
## represents a Nim seq as YAML sequence
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
c.put(startSeqEvent(tag = tag))
|
c.put(startSeqEvent(tag = tag))
|
||||||
|
@ -452,7 +443,7 @@ proc representObject*[T](value: seq[T]|set[T], ts: TagStyle,
|
||||||
representChild(item, childTagStyle, c)
|
representChild(item, childTagStyle, c)
|
||||||
c.put(endSeqEvent())
|
c.put(endSeqEvent())
|
||||||
|
|
||||||
proc yamlTag*[I, V](T: typedesc[array[I, V]]): TagId {.inline, raises: [].} =
|
proc yamlTag*[I, V](T: typedesc[array[I, V]]): Tag {.inline, raises: [].} =
|
||||||
const rangeName = name(I)
|
const rangeName = name(I)
|
||||||
let uri = nimTag("system:array(" & rangeName[6..rangeName.high()] & ';' &
|
let uri = nimTag("system:array(" & rangeName[6..rangeName.high()] & ';' &
|
||||||
safeTagUri(yamlTag(V)) & ')')
|
safeTagUri(yamlTag(V)) & ')')
|
||||||
|
@ -475,7 +466,7 @@ proc constructObject*[I, T](s: var YamlStream, c: ConstructionContext,
|
||||||
raise s.constructionError(event.startPos, "Too many array values")
|
raise s.constructionError(event.startPos, "Too many array values")
|
||||||
|
|
||||||
proc representObject*[I, T](value: array[I, T], ts: TagStyle,
|
proc representObject*[I, T](value: array[I, T], ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) =
|
c: SerializationContext, tag: Tag) =
|
||||||
## represents a Nim array as YAML sequence
|
## represents a Nim array as YAML sequence
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
c.put(startSeqEvent(tag = tag))
|
c.put(startSeqEvent(tag = tag))
|
||||||
|
@ -483,7 +474,7 @@ proc representObject*[I, T](value: array[I, T], ts: TagStyle,
|
||||||
representChild(item, childTagStyle, c)
|
representChild(item, childTagStyle, c)
|
||||||
c.put(endSeqEvent())
|
c.put(endSeqEvent())
|
||||||
|
|
||||||
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
|
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): Tag {.inline, raises: [].} =
|
||||||
try:
|
try:
|
||||||
let uri = nimTag("tables:Table(" & safeTagUri(yamlTag(K)) & ';' &
|
let uri = nimTag("tables:Table(" & safeTagUri(yamlTag(K)) & ';' &
|
||||||
safeTagUri(yamlTag(V)) & ")")
|
safeTagUri(yamlTag(V)) & ")")
|
||||||
|
@ -512,7 +503,7 @@ proc constructObject*[K, V](s: var YamlStream, c: ConstructionContext,
|
||||||
discard s.next()
|
discard s.next()
|
||||||
|
|
||||||
proc representObject*[K, V](value: Table[K, V], ts: TagStyle,
|
proc representObject*[K, V](value: Table[K, V], ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) =
|
c: SerializationContext, tag: Tag) =
|
||||||
## represents a Nim Table as YAML mapping
|
## represents a Nim Table as YAML mapping
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
c.put(startMapEvent(tag = tag))
|
c.put(startMapEvent(tag = tag))
|
||||||
|
@ -521,7 +512,7 @@ proc representObject*[K, V](value: Table[K, V], ts: TagStyle,
|
||||||
representChild(value, childTagStyle, c)
|
representChild(value, childTagStyle, c)
|
||||||
c.put(endMapEvent())
|
c.put(endMapEvent())
|
||||||
|
|
||||||
proc yamlTag*[K, V](T: typedesc[OrderedTable[K, V]]): TagId
|
proc yamlTag*[K, V](T: typedesc[OrderedTable[K, V]]): Tag
|
||||||
{.inline, raises: [].} =
|
{.inline, raises: [].} =
|
||||||
try:
|
try:
|
||||||
let uri = nimTag("tables:OrderedTable(" & safeTagUri(yamlTag(K)) & ';' &
|
let uri = nimTag("tables:OrderedTable(" & safeTagUri(yamlTag(K)) & ';' &
|
||||||
|
@ -557,7 +548,7 @@ proc constructObject*[K, V](s: var YamlStream, c: ConstructionContext,
|
||||||
discard s.next()
|
discard s.next()
|
||||||
|
|
||||||
proc representObject*[K, V](value: OrderedTable[K, V], ts: TagStyle,
|
proc representObject*[K, V](value: OrderedTable[K, V], ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) =
|
c: SerializationContext, tag: Tag) =
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
c.put(startSeqEvent(tag = tag))
|
c.put(startSeqEvent(tag = tag))
|
||||||
for key, value in value.pairs:
|
for key, value in value.pairs:
|
||||||
|
@ -568,13 +559,13 @@ proc representObject*[K, V](value: OrderedTable[K, V], ts: TagStyle,
|
||||||
c.put(endSeqEvent())
|
c.put(endSeqEvent())
|
||||||
|
|
||||||
proc yamlTag*(T: typedesc[object|enum]):
|
proc yamlTag*(T: typedesc[object|enum]):
|
||||||
TagId {.inline, raises: [].} =
|
Tag {.inline, raises: [].} =
|
||||||
var uri = nimTag("custom:" & (typetraits.name(type(T))))
|
var uri = nimTag("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, raises: [].} =
|
Tag {.inline, raises: [].} =
|
||||||
var
|
var
|
||||||
i: T
|
i: T
|
||||||
uri = nimTag("tuple(")
|
uri = nimTag("tuple(")
|
||||||
|
@ -999,7 +990,7 @@ macro genRepresentObject(t: typedesc, value, childTagStyle: typed) =
|
||||||
inc(fieldIndex)
|
inc(fieldIndex)
|
||||||
|
|
||||||
proc representObject*[O: object](value: O, ts: TagStyle,
|
proc representObject*[O: object](value: O, ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) =
|
c: SerializationContext, tag: Tag) =
|
||||||
## represents a Nim object or tuple as YAML mapping
|
## represents a Nim object or tuple as YAML mapping
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
when isVariantObject(getType(O)): c.put(startSeqEvent(tag = tag))
|
when isVariantObject(getType(O)): c.put(startSeqEvent(tag = tag))
|
||||||
|
@ -1009,7 +1000,7 @@ proc representObject*[O: object](value: O, ts: TagStyle,
|
||||||
else: c.put(endMapEvent())
|
else: c.put(endMapEvent())
|
||||||
|
|
||||||
proc representObject*[O: tuple](value: O, ts: TagStyle,
|
proc representObject*[O: tuple](value: O, ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) =
|
c: SerializationContext, tag: Tag) =
|
||||||
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
let childTagStyle = if ts == tsRootOnly: tsNone else: ts
|
||||||
var fieldIndex = 0'i16
|
var fieldIndex = 0'i16
|
||||||
c.put(startMapEvent(tag = tag))
|
c.put(startMapEvent(tag = tag))
|
||||||
|
@ -1035,13 +1026,13 @@ proc constructObject*[O: enum](s: var YamlStream, c: ConstructionContext,
|
||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
proc representObject*[O: enum](value: O, ts: TagStyle,
|
proc representObject*[O: enum](value: O, ts: TagStyle,
|
||||||
c: SerializationContext, tag: TagId) {.raises: [].} =
|
c: SerializationContext, tag: Tag) {.raises: [].} =
|
||||||
## represents a Nim enum as YAML scalar
|
## represents a Nim enum as YAML scalar
|
||||||
c.put(scalarEvent($value, tag, yAnchorNone))
|
c.put(scalarEvent($value, tag, yAnchorNone))
|
||||||
|
|
||||||
proc yamlTag*[O](T: typedesc[ref O]): TagId {.inline, raises: [].} = yamlTag(O)
|
proc yamlTag*[O](T: typedesc[ref O]): Tag {.inline, raises: [].} = yamlTag(O)
|
||||||
|
|
||||||
macro constructImplicitVariantObject(s, m, c, r, possibleTagIds: untyped,
|
macro constructImplicitVariantObject(s, m, c, r, possibleTags: untyped,
|
||||||
t: typedesc) =
|
t: typedesc) =
|
||||||
let tDesc = getType(getType(t)[1])
|
let tDesc = getType(getType(t)[1])
|
||||||
yAssert tDesc.kind == nnkObjectTy
|
yAssert tDesc.kind == nnkObjectTy
|
||||||
|
@ -1058,12 +1049,12 @@ macro constructImplicitVariantObject(s, m, c, r, possibleTagIds: untyped,
|
||||||
)))
|
)))
|
||||||
case recCase[i][1].recListLen
|
case recCase[i][1].recListLen
|
||||||
of 0:
|
of 0:
|
||||||
branch.add(infix(newIdentNode("yTagNull"), "in", possibleTagIds))
|
branch.add(infix(newIdentNode("yTagNull"), "in", possibleTags))
|
||||||
branchContent.add(newNimNode(nnkDiscardStmt).add(newCall("next", s)))
|
branchContent.add(newNimNode(nnkDiscardStmt).add(newCall("next", s)))
|
||||||
of 1:
|
of 1:
|
||||||
let field = newDotExpr(r, newIdentNode($recCase[i][1].recListNode))
|
let field = newDotExpr(r, newIdentNode($recCase[i][1].recListNode))
|
||||||
branch.add(infix(
|
branch.add(infix(
|
||||||
newCall("yamlTag", newCall("type", field)), "in", possibleTagIds))
|
newCall("yamlTag", newCall("type", field)), "in", possibleTags))
|
||||||
branchContent.add(newCall("constructChild", s, c, field))
|
branchContent.add(newCall("constructChild", s, c, field))
|
||||||
else:
|
else:
|
||||||
block:
|
block:
|
||||||
|
@ -1074,8 +1065,7 @@ macro constructImplicitVariantObject(s, m, c, r, possibleTagIds: untyped,
|
||||||
newCall(bindSym("constructionError"), s, m,
|
newCall(bindSym("constructionError"), s, m,
|
||||||
infix(newStrLitNode("This value type does not map to any field in " &
|
infix(newStrLitNode("This value type does not map to any field in " &
|
||||||
getTypeImpl(t)[1].repr & ": "), "&",
|
getTypeImpl(t)[1].repr & ": "), "&",
|
||||||
newCall("uri", newIdentNode("serializationTagLibrary"),
|
newCall("$", newNimNode(nnkBracketExpr).add(possibleTags, newIntLitNode(0)))
|
||||||
newNimNode(nnkBracketExpr).add(possibleTagIds, newIntLitNode(0)))
|
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
result.add(newNimNode(nnkElse).add(newNimNode(nnkTryStmt).add(
|
result.add(newNimNode(nnkElse).add(newNimNode(nnkTryStmt).add(
|
||||||
|
@ -1111,45 +1101,45 @@ proc constructChild*[T](s: var YamlStream, c: ConstructionContext,
|
||||||
when isImplicitVariantObject(T):
|
when isImplicitVariantObject(T):
|
||||||
when not canBeImplicit(T):
|
when not canBeImplicit(T):
|
||||||
{. fatal: "This type cannot be marked as implicit" .}
|
{. fatal: "This type cannot be marked as implicit" .}
|
||||||
var possibleTagIds = newSeq[TagId]()
|
var possibleTags = newSeq[Tag]()
|
||||||
case item.kind
|
case item.kind
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
case item.scalarProperties.tag
|
case item.scalarProperties.tag
|
||||||
of yTagQuestionMark:
|
of yTagQuestionMark:
|
||||||
case guessType(item.scalarContent)
|
case guessType(item.scalarContent)
|
||||||
of yTypeInteger:
|
of yTypeInteger:
|
||||||
possibleTagIds.add([yamlTag(int), yamlTag(int8), yamlTag(int16),
|
possibleTags.add([yamlTag(int), yamlTag(int8), yamlTag(int16),
|
||||||
yamlTag(int32), yamlTag(int64)])
|
yamlTag(int32), yamlTag(int64)])
|
||||||
if item.scalarContent[0] != '-':
|
if item.scalarContent[0] != '-':
|
||||||
possibleTagIds.add([yamlTag(uint), yamlTag(uint8), yamlTag(uint16),
|
possibleTags.add([yamlTag(uint), yamlTag(uint8), yamlTag(uint16),
|
||||||
yamlTag(uint32), yamlTag(uint64)])
|
yamlTag(uint32), yamlTag(uint64)])
|
||||||
of yTypeFloat, yTypeFloatInf, yTypeFloatNaN:
|
of yTypeFloat, yTypeFloatInf, yTypeFloatNaN:
|
||||||
possibleTagIds.add([yamlTag(float), yamlTag(float32),
|
possibleTags.add([yamlTag(float), yamlTag(float32),
|
||||||
yamlTag(float64)])
|
yamlTag(float64)])
|
||||||
of yTypeBoolTrue, yTypeBoolFalse:
|
of yTypeBoolTrue, yTypeBoolFalse:
|
||||||
possibleTagIds.add(yamlTag(bool))
|
possibleTags.add(yamlTag(bool))
|
||||||
of yTypeNull:
|
of yTypeNull:
|
||||||
raise s.constructionError(item.startPos, "not implemented!")
|
raise s.constructionError(item.startPos, "not implemented!")
|
||||||
of yTypeUnknown:
|
of yTypeUnknown:
|
||||||
possibleTagIds.add(yamlTag(string))
|
possibleTags.add(yamlTag(string))
|
||||||
of yTypeTimestamp:
|
of yTypeTimestamp:
|
||||||
possibleTagIds.add(yamlTag(Time))
|
possibleTags.add(yamlTag(Time))
|
||||||
of yTagExclamationMark:
|
of yTagExclamationMark:
|
||||||
possibleTagIds.add(yamlTag(string))
|
possibleTags.add(yamlTag(string))
|
||||||
else:
|
else:
|
||||||
possibleTagIds.add(item.scalarProperties.tag)
|
possibleTags.add(item.scalarProperties.tag)
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
if item.mapProperties.tag in [yTagQuestionMark, yTagExclamationMark]:
|
if item.mapProperties.tag in [yTagQuestionMark, yTagExclamationMark]:
|
||||||
raise s.constructionError(item.startPos,
|
raise s.constructionError(item.startPos,
|
||||||
"Complex value of implicit variant object type must have a tag.")
|
"Complex value of implicit variant object type must have a tag.")
|
||||||
possibleTagIds.add(item.mapProperties.tag)
|
possibleTags.add(item.mapProperties.tag)
|
||||||
of yamlStartSeq:
|
of yamlStartSeq:
|
||||||
if item.seqProperties.tag in [yTagQuestionMark, yTagExclamationMark]:
|
if item.seqProperties.tag in [yTagQuestionMark, yTagExclamationMark]:
|
||||||
raise s.constructionError(item.startPos,
|
raise s.constructionError(item.startPos,
|
||||||
"Complex value of implicit variant object type must have a tag.")
|
"Complex value of implicit variant object type must have a tag.")
|
||||||
possibleTagIds.add(item.seqProperties.tag)
|
possibleTags.add(item.seqProperties.tag)
|
||||||
else: internalError("Unexpected item kind: " & $item.kind)
|
else: internalError("Unexpected item kind: " & $item.kind)
|
||||||
constructImplicitVariantObject(s, item.startPos, c, result, possibleTagIds, T)
|
constructImplicitVariantObject(s, item.startPos, c, result, possibleTags, T)
|
||||||
else:
|
else:
|
||||||
case item.kind
|
case item.kind
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
|
@ -1233,20 +1223,14 @@ proc constructChild*[O](s: var YamlStream, c: ConstructionContext,
|
||||||
discard s.next()
|
discard s.next()
|
||||||
return
|
return
|
||||||
elif e.kind == yamlAlias:
|
elif e.kind == yamlAlias:
|
||||||
when defined(JS):
|
result = cast[ref O](c.refs.getOrDefault(e.aliasTarget).p)
|
||||||
{.emit: [result, """ = """, c, """.refs.get(""", e.aliasTarget, """);"""].}
|
|
||||||
else:
|
|
||||||
result = cast[ref O](c.refs.getOrDefault(e.aliasTarget))
|
|
||||||
discard s.next()
|
discard s.next()
|
||||||
return
|
return
|
||||||
new(result)
|
new(result)
|
||||||
template removeAnchor(anchor: var Anchor) {.dirty.} =
|
template removeAnchor(anchor: var Anchor) {.dirty.} =
|
||||||
if anchor != yAnchorNone:
|
if anchor != yAnchorNone:
|
||||||
when defined(JS):
|
|
||||||
{.emit: [c, """.refs.set(""", anchor, """, """, result, """);"""].}
|
|
||||||
else:
|
|
||||||
yAssert(not c.refs.hasKey(anchor))
|
yAssert(not c.refs.hasKey(anchor))
|
||||||
c.refs[anchor] = cast[pointer](result)
|
c.refs[anchor] = (0, cast[pointer](result))
|
||||||
anchor = yAnchorNone
|
anchor = yAnchorNone
|
||||||
|
|
||||||
case e.kind
|
case e.kind
|
||||||
|
@ -1280,50 +1264,33 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext) =
|
||||||
if isNil(value): c.put(scalarEvent("~", yTagNull))
|
if isNil(value): c.put(scalarEvent("~", yTagNull))
|
||||||
elif c.style == asNone: representChild(value[], ts, c)
|
elif c.style == asNone: representChild(value[], ts, c)
|
||||||
else:
|
else:
|
||||||
var val: Anchor
|
var val: tuple[a: Anchor, referenced: bool]
|
||||||
when defined(JS):
|
|
||||||
{.emit: ["""
|
|
||||||
if (""", c, """.refs.has(""", value, """) {
|
|
||||||
""", val, """ = """, c, """.refs.get(""", value, """);
|
|
||||||
if (val == """, yAnchorNone, ") {"].}
|
|
||||||
val = c.nextAnchorId
|
|
||||||
{.emit: [c, """.refs.set(""", value, """, """, val, """);"""].}
|
|
||||||
nextAnchor(c, len(c.nextAnchorId) - 1)
|
|
||||||
{.emit: "}".}
|
|
||||||
c.put(aliasEvent(val))
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
let p = cast[pointer](value)
|
let p = cast[pointer](value)
|
||||||
if c.refs.hasKey(p):
|
if c.refs.hasKey(p):
|
||||||
val = c.refs.getOrDefault(p)
|
val = c.refs.getOrDefault(p)
|
||||||
if val == yAnchorNone:
|
yAssert(val.a != yAnchorNone)
|
||||||
val = c.nextAnchorId.Anchor
|
if not val.referenced:
|
||||||
|
c.refs[p] = (val.a, true)
|
||||||
|
c.put(aliasEvent(val.a))
|
||||||
|
return
|
||||||
|
if c.style != asNone:
|
||||||
|
val = (c.nextAnchorId.Anchor, false)
|
||||||
c.refs[p] = val
|
c.refs[p] = val
|
||||||
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
||||||
c.put(aliasEvent(val))
|
|
||||||
return
|
|
||||||
if c.style == asAlways:
|
|
||||||
val = c.nextAnchorId.Anchor
|
|
||||||
when defined(JS):
|
|
||||||
{.emit: [c, ".refs.set(", p, ", ", val, ");"].}
|
|
||||||
else: c.refs[p] = val
|
|
||||||
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
|
||||||
else: c.refs[p] = yAnchorNone
|
|
||||||
let
|
let
|
||||||
a = if c.style == asAlways: val else: cast[Anchor](p)
|
|
||||||
childTagStyle = if ts == tsAll: tsAll else: tsRootOnly
|
childTagStyle = if ts == tsAll: tsAll else: tsRootOnly
|
||||||
origPut = c.put
|
origPut = c.put
|
||||||
c.put = proc(e: Event) =
|
c.put = proc(e: Event) =
|
||||||
var ex = e
|
var ex = e
|
||||||
case ex.kind
|
case ex.kind
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
ex.mapProperties.anchor = a
|
ex.mapProperties.anchor = val.a
|
||||||
if ts == tsNone: ex.mapProperties.tag = yTagQuestionMark
|
if ts == tsNone: ex.mapProperties.tag = yTagQuestionMark
|
||||||
of yamlStartSeq:
|
of yamlStartSeq:
|
||||||
ex.seqProperties.anchor = a
|
ex.seqProperties.anchor = val.a
|
||||||
if ts == tsNone: ex.seqProperties.tag = yTagQuestionMark
|
if ts == tsNone: ex.seqProperties.tag = yTagQuestionMark
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
ex.scalarProperties.anchor = a
|
ex.scalarProperties.anchor = val.a
|
||||||
if ts == tsNone and guessType(ex.scalarContent) != yTypeNull:
|
if ts == tsNone and guessType(ex.scalarContent) != yTypeNull:
|
||||||
ex.scalarProperties.tag = yTagQuestionMark
|
ex.scalarProperties.tag = yTagQuestionMark
|
||||||
else: discard
|
else: discard
|
||||||
|
@ -1401,6 +1368,10 @@ proc load*[K](input: Stream | string, target: var K)
|
||||||
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
|
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
|
||||||
else: internalError("Unexpected exception: " & $e.parent.name)
|
else: internalError("Unexpected exception: " & $e.parent.name)
|
||||||
|
|
||||||
|
proc loadAs*[K](input: string): K {.raises: [YamlConstructionError, IOError, YamlParserError].} =
|
||||||
|
## Loads the given YAML input to a value of the type K and returns it
|
||||||
|
load(input, result)
|
||||||
|
|
||||||
proc loadMultiDoc*[K](input: Stream | string, target: var seq[K]) =
|
proc loadMultiDoc*[K](input: Stream | string, target: var seq[K]) =
|
||||||
var
|
var
|
||||||
parser = initYamlParser(serializationTagLibrary)
|
parser = initYamlParser(serializationTagLibrary)
|
||||||
|
@ -1427,10 +1398,10 @@ proc loadMultiDoc*[K](input: Stream | string, target: var seq[K]) =
|
||||||
proc setAnchor(a: var Anchor, c: var SerializationContext)
|
proc setAnchor(a: var Anchor, c: var SerializationContext)
|
||||||
{.inline.} =
|
{.inline.} =
|
||||||
if a != yAnchorNone:
|
if a != yAnchorNone:
|
||||||
when defined(JS):
|
for key, val in c.refs:
|
||||||
{.emit: [a, """ = """, c, """.refs.get(""", a, """);"""].}
|
if val.a == a:
|
||||||
else:
|
if not val.referenced: a = yAnchorNone
|
||||||
a = c.refs.getOrDefault(cast[pointer](a))
|
return
|
||||||
|
|
||||||
proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
||||||
a: AnchorStyle = asTidy): YamlStream =
|
a: AnchorStyle = asTidy): YamlStream =
|
||||||
|
|
|
@ -28,29 +28,19 @@ type
|
||||||
## them with `initFailsafeTagLibrary <#initFailsafeTagLibrary>`_,
|
## them with `initFailsafeTagLibrary <#initFailsafeTagLibrary>`_,
|
||||||
## `initCoreTagLibrary <#initCoreTagLibrary>`_ or
|
## `initCoreTagLibrary <#initCoreTagLibrary>`_ or
|
||||||
## `initExtendedTagLibrary <#initExtendedTagLibrary>`_.
|
## `initExtendedTagLibrary <#initExtendedTagLibrary>`_.
|
||||||
tags*: Table[string, TagId]
|
tags*: Table[string, Tag]
|
||||||
nextCustomTagId*: TagId
|
|
||||||
|
|
||||||
proc initTagLibrary*(): TagLibrary {.raises: [].} =
|
proc initTagLibrary*(): TagLibrary {.raises: [].} =
|
||||||
## initializes the ``tags`` table and sets ``nextCustomTagId`` to
|
## initializes the ``tags`` table and sets ``nextCustomTagId`` to
|
||||||
## ``yFirstCustomTagId``.
|
## ``yFirstCustomTagId``.
|
||||||
new(result)
|
new(result)
|
||||||
result.tags = initTable[string, TagId]()
|
result.tags = initTable[string, Tag]()
|
||||||
|
|
||||||
result.nextCustomTagId = yFirstCustomTagId
|
proc registerUri*(tagLib: TagLibrary, uri: string): Tag {.raises: [].} =
|
||||||
|
|
||||||
proc registerUri*(tagLib: TagLibrary, uri: string): TagId {.raises: [].} =
|
|
||||||
## registers a custom tag URI with a ``TagLibrary``. The URI will get
|
## registers a custom tag URI with a ``TagLibrary``. The URI will get
|
||||||
## the ``TagId`` ``nextCustomTagId``, which will be incremented.
|
## the ``TagId`` ``nextCustomTagId``, which will be incremented.
|
||||||
tagLib.tags[uri] = tagLib.nextCustomTagId
|
result = uri.Tag
|
||||||
result = tagLib.nextCustomTagId
|
tagLib.tags[uri] = result
|
||||||
tagLib.nextCustomTagId = cast[TagId](cast[int](tagLib.nextCustomTagId) + 1)
|
|
||||||
|
|
||||||
proc uri*(tagLib: TagLibrary, id: TagId): string {.raises: [KeyError].} =
|
|
||||||
## retrieve the URI a ``TagId`` maps to.
|
|
||||||
for iUri, iId in tagLib.tags.pairs:
|
|
||||||
if iId == id: return iUri
|
|
||||||
raise newException(KeyError, "Unknown tag id: " & $id)
|
|
||||||
|
|
||||||
template y(suffix: string): string = yamlTagRepositoryPrefix & suffix
|
template y(suffix: string): string = yamlTagRepositoryPrefix & suffix
|
||||||
template n(suffix: string): string = nimyamlTagRepositoryPrefix & suffix
|
template n(suffix: string): string = nimyamlTagRepositoryPrefix & suffix
|
||||||
|
@ -114,7 +104,7 @@ proc initSerializationTagLibrary*(): TagLibrary =
|
||||||
result.tags[n"field"] = yTagNimField
|
result.tags[n"field"] = yTagNimField
|
||||||
|
|
||||||
var
|
var
|
||||||
serializationTagLibrary* = initSerializationTagLibrary() ## \
|
serializationTagLibrary* {.compileTime.} = initSerializationTagLibrary() ## \
|
||||||
## contains all local tags that are used for type serialization. Does
|
## contains all local tags that are used for type serialization. Does
|
||||||
## not contain any of the specific default tags for sequences or maps,
|
## not contain any of the specific default tags for sequences or maps,
|
||||||
## as those are not suited for Nim's static type system.
|
## as those are not suited for Nim's static type system.
|
||||||
|
@ -123,8 +113,6 @@ var
|
||||||
## `serializable <#serializable,stmt,stmt>`_.
|
## `serializable <#serializable,stmt,stmt>`_.
|
||||||
|
|
||||||
var
|
var
|
||||||
nextStaticTagId {.compileTime.} = yFirstStaticTagId ## \
|
|
||||||
## used for generating unique TagIds with ``setTagUri``.
|
|
||||||
registeredUris {.compileTime.} = newSeq[string]() ## \
|
registeredUris {.compileTime.} = newSeq[string]() ## \
|
||||||
## Since Table doesn't really work at compile time, we also store
|
## Since Table doesn't really work at compile time, we also store
|
||||||
## registered URIs here to be able to generate a static compiler error
|
## registered URIs here to be able to generate a static compiler error
|
||||||
|
@ -135,14 +123,11 @@ template setTagUri*(t: typedesc, uri: string) =
|
||||||
## when loading and dumping values of this type.
|
## when loading and dumping values of this type.
|
||||||
when uri in registeredUris:
|
when uri in registeredUris:
|
||||||
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
|
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
|
||||||
const id {.genSym.} = nextStaticTagId
|
const tag {.genSym.} = uri.Tag
|
||||||
static:
|
static:
|
||||||
registeredUris.add(uri)
|
registeredUris.add(uri)
|
||||||
nextStaticTagId = TagId(int(nextStaticTagId) + 1)
|
serializationTagLibrary.tags[uri] = tag
|
||||||
when nextStaticTagId == yFirstCustomTagId:
|
proc yamlTag*(T: typedesc[t]): Tag {.inline, raises: [].} = tag
|
||||||
{.fatal: "Too many tags!".}
|
|
||||||
serializationTagLibrary.tags[uri] = id
|
|
||||||
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = id
|
|
||||||
## autogenerated
|
## autogenerated
|
||||||
|
|
||||||
template setTagUri*(t: typedesc, uri: string, idName: untyped) =
|
template setTagUri*(t: typedesc, uri: string, idName: untyped) =
|
||||||
|
@ -151,14 +136,11 @@ template setTagUri*(t: typedesc, uri: string, idName: untyped) =
|
||||||
## necessary if you want to implement serialization / construction yourself.
|
## necessary if you want to implement serialization / construction yourself.
|
||||||
when uri in registeredUris:
|
when uri in registeredUris:
|
||||||
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
|
{. fatal: "[NimYAML] URI \"" & uri & "\" registered twice!" .}
|
||||||
const idName* = nextStaticTagId
|
const idName* = uri.Tag
|
||||||
static:
|
static:
|
||||||
registeredUris.add(uri)
|
registeredUris.add(uri)
|
||||||
nextStaticTagId = TagId(int(nextStaticTagId) + 1)
|
|
||||||
when nextStaticTagId == yFirstCustomTagId:
|
|
||||||
{.fatal: "Too many tags!".}
|
|
||||||
serializationTagLibrary.tags[uri] = idName
|
serializationTagLibrary.tags[uri] = idName
|
||||||
proc yamlTag*(T: typedesc[t]): TagId {.inline, raises: [].} = idName
|
proc yamlTag*(T: typedesc[t]): Tag {.inline, raises: [].} = idName
|
||||||
## autogenerated
|
## autogenerated
|
||||||
|
|
||||||
static:
|
static:
|
||||||
|
|
|
@ -21,7 +21,7 @@ type Level = tuple[node: JsonNode, key: string, expKey: bool]
|
||||||
proc initLevel(node: JsonNode): Level {.raises: [].} =
|
proc initLevel(node: JsonNode): Level {.raises: [].} =
|
||||||
(node: node, key: "", expKey: true)
|
(node: node, key: "", expKey: true)
|
||||||
|
|
||||||
proc jsonFromScalar(content: string, tag: TagId): JsonNode
|
proc jsonFromScalar(content: string, tag: Tag): JsonNode
|
||||||
{.raises: [YamlConstructionError].}=
|
{.raises: [YamlConstructionError].}=
|
||||||
new(result)
|
new(result)
|
||||||
var mappedType: TypeHint
|
var mappedType: TypeHint
|
||||||
|
|
Loading…
Reference in New Issue