mirror of https://github.com/status-im/NimYAML.git
started updating other parts of the codebase
This commit is contained in:
parent
05b8528f3e
commit
1d707b184e
|
@ -170,7 +170,7 @@ proc endDocEvent*(explicit: bool = false, startPos, endPos: Mark = defaultMark):
|
|||
kind: yamlEndDoc, explicitDocumentEnd: explicit)
|
||||
|
||||
proc startMapEvent*(style: CollectionStyle, props: Properties,
|
||||
startPos, endPos: Mark): Event {.inline, raises: [].} =
|
||||
startPos, endPos: Mark = defaultMark): Event {.inline, raises: [].} =
|
||||
## creates a new event that marks the start of a YAML mapping
|
||||
result = Event(startPos: startPos, endPos: endPos,
|
||||
kind: yamlStartMap, mapProperties: props,
|
||||
|
|
59
yaml/dom.nim
59
yaml/dom.nim
|
@ -20,7 +20,7 @@
|
|||
## objects of Nim's `json module <http://nim-lang.org/docs/json.html>`_.
|
||||
|
||||
import tables, streams, hashes, sets, strutils
|
||||
import stream, taglib, serialization, private/internal, parser,
|
||||
import data, stream, taglib, serialization, private/internal, parser,
|
||||
presenter
|
||||
|
||||
when defined(nimNoNil):
|
||||
|
@ -129,12 +129,13 @@ proc newYamlNode*(fields: openarray[(YamlNode, YamlNode)],
|
|||
tag: string = "?"): YamlNode =
|
||||
YamlNode(kind: yMapping, fields: newTable(fields), tag: tag)
|
||||
|
||||
proc initYamlDoc*(root: YamlNode): YamlDocument = result.root = root
|
||||
proc initYamlDoc*(root: YamlNode): YamlDocument =
|
||||
result = YamlDocument(root: root)
|
||||
|
||||
proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
||||
c: ConstructionContext):
|
||||
YamlNode {.raises: [YamlStreamError, YamlConstructionError].} =
|
||||
template addAnchor(c: ConstructionContext, target: AnchorId) =
|
||||
template addAnchor(c: ConstructionContext, target: Anchor) =
|
||||
if target != yAnchorNone:
|
||||
when defined(JS):
|
||||
{.emit: [c, """.refs.set(""", target, ", ", result, ");"].}
|
||||
|
@ -142,13 +143,13 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
|||
yAssert(not c.refs.hasKey(target))
|
||||
c.refs[target] = cast[pointer](result)
|
||||
|
||||
var start: YamlStreamEvent
|
||||
var start: Event
|
||||
shallowCopy(start, s.next())
|
||||
new(result)
|
||||
try:
|
||||
case start.kind
|
||||
of yamlStartMap:
|
||||
result = YamlNode(tag: tagLib.uri(start.mapTag),
|
||||
result = YamlNode(tag: tagLib.uri(start.mapProperties.tag),
|
||||
kind: yMapping,
|
||||
fields: newTable[YamlNode, YamlNode]())
|
||||
while s.peek().kind != yamlEndMap:
|
||||
|
@ -159,20 +160,20 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
|||
raise newException(YamlConstructionError,
|
||||
"Duplicate key: " & $key)
|
||||
discard s.next()
|
||||
addAnchor(c, start.mapAnchor)
|
||||
addAnchor(c, start.mapProperties.anchor)
|
||||
of yamlStartSeq:
|
||||
result = YamlNode(tag: tagLib.uri(start.seqTag),
|
||||
result = YamlNode(tag: tagLib.uri(start.seqProperties.tag),
|
||||
kind: ySequence,
|
||||
elems: newSeq[YamlNode]())
|
||||
while s.peek().kind != yamlEndSeq:
|
||||
result.elems.add(composeNode(s, tagLib, c))
|
||||
addAnchor(c, start.seqAnchor)
|
||||
addAnchor(c, start.seqProperties.anchor)
|
||||
discard s.next()
|
||||
of yamlScalar:
|
||||
result = YamlNode(tag: tagLib.uri(start.scalarTag),
|
||||
result = YamlNode(tag: tagLib.uri(start.scalarProperties.tag),
|
||||
kind: yScalar)
|
||||
shallowCopy(result.content, start.scalarContent)
|
||||
addAnchor(c, start.scalarAnchor)
|
||||
addAnchor(c, start.scalarProperties.anchor)
|
||||
of yamlAlias:
|
||||
when defined(JS):
|
||||
{.emit: [result, " = ", c, ".refs.get(", start.aliasTarget, ");"].}
|
||||
|
@ -186,10 +187,10 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
|||
proc compose*(s: var YamlStream, tagLib: TagLibrary): YamlDocument
|
||||
{.raises: [YamlStreamError, YamlConstructionError].} =
|
||||
var context = newConstructionContext()
|
||||
var n: YamlStreamEvent
|
||||
var n: Event
|
||||
shallowCopy(n, s.next())
|
||||
yAssert n.kind == yamlStartDoc
|
||||
result.root = composeNode(s, tagLib, context)
|
||||
result = YamlDocument(root: composeNode(s, tagLib, context))
|
||||
n = s.next()
|
||||
yAssert n.kind == yamlEndDoc
|
||||
|
||||
|
@ -228,21 +229,21 @@ proc serializeNode(n: YamlNode, c: SerializationContext, a: AnchorStyle,
|
|||
if a != asNone and c.refs.hasKey(p):
|
||||
val = c.refs.getOrDefault(p)
|
||||
if val == yAnchorNone:
|
||||
val = c.nextAnchorId
|
||||
val = c.nextAnchorId.Anchor
|
||||
c.refs[p] = val
|
||||
c.nextAnchorId = AnchorId(int(c.nextAnchorId) + 1)
|
||||
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
||||
c.put(aliasEvent(val))
|
||||
return
|
||||
var
|
||||
tagId: TagId
|
||||
anchor: AnchorId
|
||||
anchor: Anchor
|
||||
if a == asAlways:
|
||||
val = c.nextAnchorId
|
||||
val = c.nextAnchorId.Anchor
|
||||
when defined(JS):
|
||||
{.emit: [c, ".refs.set(", n, ", ", val, ");"].}
|
||||
else:
|
||||
c.refs[p] = c.nextAnchorId
|
||||
c.nextAnchorId = AnchorId(int(val) + 1)
|
||||
c.refs[p] = c.nextAnchorId.Anchor
|
||||
nextAnchor(c.nextAnchorId, len(c.nextAnchorId) - 1)
|
||||
else:
|
||||
when defined(JS):
|
||||
{.emit: [c, ".refs.set(", n, ", ", yAnchorNone, ");"].}
|
||||
|
@ -252,37 +253,37 @@ proc serializeNode(n: YamlNode, c: SerializationContext, a: AnchorStyle,
|
|||
tagLib.registerUri(n.tag)
|
||||
case a
|
||||
of asNone: anchor = yAnchorNone
|
||||
of asTidy: anchor = cast[AnchorId](n)
|
||||
of asTidy: anchor = cast[Anchor](n)
|
||||
of asAlways: anchor = val
|
||||
|
||||
case n.kind
|
||||
of yScalar: c.put(scalarEvent(n.content, tagId, anchor))
|
||||
of ySequence:
|
||||
c.put(startSeqEvent(tagId, anchor))
|
||||
c.put(startSeqEvent(csBlock, (anchor, tagId)))
|
||||
for item in n.elems:
|
||||
serializeNode(item, c, a, tagLib)
|
||||
c.put(endSeqEvent())
|
||||
of yMapping:
|
||||
c.put(startMapEvent(tagId, anchor))
|
||||
c.put(startMapEvent(csBlock, (anchor, tagId)))
|
||||
for key, value in n.fields.pairs:
|
||||
serializeNode(key, c, a, tagLib)
|
||||
serializeNode(value, c, a, tagLib)
|
||||
c.put(endMapEvent())
|
||||
|
||||
template processAnchoredEvent(target: untyped, c: SerializationContext) =
|
||||
var anchorId: AnchorId
|
||||
var anchorId: Anchor
|
||||
when defined(JS):
|
||||
{.emit: [anchorId, " = ", c, ".refs.get(", target, ");"].}
|
||||
else:
|
||||
anchorId = c.refs.getOrDefault(cast[pointer](target))
|
||||
if anchorId != yAnchorNone: target = anchorId
|
||||
else: target = yAnchorNone
|
||||
anchorId = c.refs.getOrDefault(cast[pointer](target.anchor))
|
||||
if anchorId != yAnchorNone: target.anchor = anchorId
|
||||
else: target.anchor = yAnchorNone
|
||||
|
||||
proc serialize*(doc: YamlDocument, tagLib: TagLibrary, a: AnchorStyle = asTidy):
|
||||
YamlStream {.raises: [].} =
|
||||
var
|
||||
bys = newBufferYamlStream()
|
||||
c = newSerializationContext(a, proc(e: YamlStreamEvent) {.raises: [].} =
|
||||
c = newSerializationContext(a, proc(e: Event) {.raises: [].} =
|
||||
bys.put(e)
|
||||
)
|
||||
c.put(startDocEvent())
|
||||
|
@ -291,9 +292,9 @@ proc serialize*(doc: YamlDocument, tagLib: TagLibrary, a: AnchorStyle = asTidy):
|
|||
if a == asTidy:
|
||||
for event in bys.mitems():
|
||||
case event.kind
|
||||
of yamlScalar: processAnchoredEvent(event.scalarAnchor, c)
|
||||
of yamlStartMap: processAnchoredEvent(event.mapAnchor, c)
|
||||
of yamlStartSeq: processAnchoredEvent(event.seqAnchor, c)
|
||||
of yamlScalar: processAnchoredEvent(event.scalarProperties, c)
|
||||
of yamlStartMap: processAnchoredEvent(event.mapProperties, c)
|
||||
of yamlStartSeq: processAnchoredEvent(event.seqProperties, c)
|
||||
else: discard
|
||||
result = bys
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ type
|
|||
issueWarnings: bool
|
||||
anchors: Table[string, Anchor]
|
||||
|
||||
State = proc(c: Context, e: var Event): bool
|
||||
State = proc(c: Context, e: var Event): bool {.locks: 0, gcSafe.}
|
||||
|
||||
Level = object
|
||||
state: State
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
## This is the presenter API, used for generating YAML character streams.
|
||||
|
||||
import streams, deques, strutils
|
||||
import taglib, stream, private/internal, hints, parser, stream
|
||||
import data, taglib, stream, private/internal, hints, parser, stream
|
||||
|
||||
type
|
||||
PresentationStyle* = enum
|
||||
|
@ -86,7 +86,7 @@ type
|
|||
newlines*: NewLineStyle
|
||||
outputVersion*: OutputYamlVersion
|
||||
|
||||
YamlPresenterJsonError* = object of Exception
|
||||
YamlPresenterJsonError* = object of ValueError
|
||||
## Exception that may be raised by the YAML presenter when it is
|
||||
## instructed to output JSON, but is unable to do so. This may occur if:
|
||||
##
|
||||
|
@ -94,7 +94,7 @@ type
|
|||
## non-scalar type as key.
|
||||
## - Any float scalar bears a ``NaN`` or positive/negative infinity value
|
||||
|
||||
YamlPresenterOutputError* = object of Exception
|
||||
YamlPresenterOutputError* = object of ValueError
|
||||
## Exception that may be raised by the YAML presenter. This occurs if
|
||||
## writing character data to the output stream raises any exception.
|
||||
## The error that has occurred is available from ``parent``.
|
||||
|
@ -398,21 +398,11 @@ proc startItem(target: PresenterTarget, style: PresentationStyle,
|
|||
e.parent = getCurrentException()
|
||||
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: PresenterTarget, tag: TagId,
|
||||
tagLib: TagLibrary,
|
||||
anchor: AnchorId) {.raises: [YamlPresenterOutputError].} =
|
||||
proc writeTagAndAnchor(target: PresenterTarget, props: Properties,
|
||||
tagLib: TagLibrary) {.raises: [YamlPresenterOutputError].} =
|
||||
try:
|
||||
if tag notin [yTagQuestionMark, yTagExclamationMark]:
|
||||
let tagUri = tagLib.uri(tag)
|
||||
if props.tag notin [yTagQuestionMark, yTagExclamationMark]:
|
||||
let tagUri = tagLib.uri(props.tag)
|
||||
let (handle, length) = tagLib.searchHandle(tagUri)
|
||||
if length > 0:
|
||||
target.append(handle)
|
||||
|
@ -422,9 +412,9 @@ proc writeTagAndAnchor(target: PresenterTarget, tag: TagId,
|
|||
target.append("!<")
|
||||
target.append(tagUri)
|
||||
target.append("> ")
|
||||
if anchor != yAnchorNone:
|
||||
if props.anchor != yAnchorNone:
|
||||
target.append("&")
|
||||
target.append(anchorName(anchor))
|
||||
target.append($props.anchor)
|
||||
target.append(' ')
|
||||
except:
|
||||
var e = newException(YamlPresenterOutputError, "")
|
||||
|
@ -432,10 +422,10 @@ proc writeTagAndAnchor(target: PresenterTarget, tag: TagId,
|
|||
raise e
|
||||
|
||||
proc nextItem(c: var Deque, s: var YamlStream):
|
||||
YamlStreamEvent {.raises: [YamlStreamError].} =
|
||||
Event {.raises: [YamlStreamError].} =
|
||||
if c.len > 0:
|
||||
try: result = c.popFirst
|
||||
except IndexError: internalError("Unexpected IndexError")
|
||||
except IndexDefect: internalError("Unexpected IndexError")
|
||||
else:
|
||||
result = s.next()
|
||||
|
||||
|
@ -445,13 +435,22 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
var
|
||||
indentation = 0
|
||||
levels = newSeq[DumperState]()
|
||||
cached = initDeQue[YamlStreamEvent]()
|
||||
cached = initDeQue[Event]()
|
||||
let newline = if options.newlines == nlLF: "\l"
|
||||
elif options.newlines == nlCRLF: "\c\l" else: "\n"
|
||||
while cached.len > 0 or not s.finished():
|
||||
var firstDoc = true
|
||||
while true:
|
||||
let item = nextItem(cached, s)
|
||||
case item.kind
|
||||
of yamlStartStream: discard
|
||||
of yamlEndStream: break
|
||||
of yamlStartDoc:
|
||||
if not firstDoc:
|
||||
if options.style == psJson:
|
||||
raise newException(YamlPresenterJsonError,
|
||||
"Cannot output more than one document in JSON style")
|
||||
target.safeWrite("..." & newline)
|
||||
|
||||
if options.style != psJson:
|
||||
try:
|
||||
case options.outputVersion
|
||||
|
@ -479,26 +478,27 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], false, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.scalarTag, tagLib, item.scalarAnchor)
|
||||
writeTagAndAnchor(target, item.scalarProperties, taglib)
|
||||
|
||||
if options.style == psJson:
|
||||
let hint = guessType(item.scalarContent)
|
||||
if item.scalarTag in [yTagQuestionMark, yTagBoolean] and
|
||||
let tag = item.scalarProperties.tag
|
||||
if tag in [yTagQuestionMark, yTagBoolean] and
|
||||
hint in {yTypeBoolTrue, yTypeBoolFalse}:
|
||||
target.safeWrite(if hint == yTypeBoolTrue: "true" else: "false")
|
||||
elif item.scalarTag in [yTagQuestionMark, yTagNull] and
|
||||
elif tag in [yTagQuestionMark, yTagNull] and
|
||||
hint == yTypeNull:
|
||||
target.safeWrite("null")
|
||||
elif item.scalarTag in [yTagQuestionMark, yTagInteger,
|
||||
elif tag in [yTagQuestionMark, yTagInteger,
|
||||
yTagNimInt8, yTagNimInt16, yTagNimInt32, yTagNimInt64,
|
||||
yTagNimUInt8, yTagNimUInt16, yTagNimUInt32, yTagNimUInt64] and
|
||||
hint == yTypeInteger:
|
||||
target.safeWrite(item.scalarContent)
|
||||
elif item.scalarTag in [yTagQuestionMark, yTagFloat, yTagNimFloat32,
|
||||
elif tag in [yTagQuestionMark, yTagFloat, yTagNimFloat32,
|
||||
yTagNimFloat64] and hint in {yTypeFloatInf, yTypeFloatNaN}:
|
||||
raise newException(YamlPresenterJsonError,
|
||||
"Infinity and not-a-number values cannot be presented as JSON!")
|
||||
elif item.scalarTag in [yTagQuestionMark, yTagFloat] and
|
||||
elif tag in [yTagQuestionMark, yTagFloat] and
|
||||
hint == yTypeFloat:
|
||||
target.safeWrite(item.scalarContent)
|
||||
else: writeDoubleQuotedJson(item.scalarContent, target)
|
||||
|
@ -525,7 +525,7 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
false, newline)
|
||||
try:
|
||||
target.append('*')
|
||||
target.append(char(byte('a') + byte(item.aliasTarget)))
|
||||
target.append($item.aliasTarget)
|
||||
except:
|
||||
var e = newException(YamlPresenterOutputError, "")
|
||||
e.parent = getCurrentException()
|
||||
|
@ -536,7 +536,6 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
of psDefault:
|
||||
var length = 0
|
||||
while true:
|
||||
yAssert(not s.finished())
|
||||
let next = s.next()
|
||||
cached.addLast(next)
|
||||
case next.kind
|
||||
|
@ -554,7 +553,6 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
nextState = dFlowSequenceStart
|
||||
of psMinimal, psCanonical: nextState = dFlowSequenceStart
|
||||
of psBlockOnly:
|
||||
yAssert(not s.finished())
|
||||
let next = s.peek()
|
||||
if next.kind == yamlEndSeq: nextState = dFlowSequenceStart
|
||||
else: nextState = dBlockSequenceItem
|
||||
|
@ -563,18 +561,18 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
case nextState
|
||||
of dBlockSequenceItem:
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.seqTag, tagLib, item.seqAnchor)
|
||||
writeTagAndAnchor(target, item.seqProperties, tagLib)
|
||||
of dFlowSequenceStart:
|
||||
target.safeWrite(newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.seqTag, tagLib, item.seqAnchor)
|
||||
writeTagAndAnchor(target, item.seqProperties, tagLib)
|
||||
indentation += options.indentationStep
|
||||
else: internalError("Invalid nextState: " & $nextState)
|
||||
else:
|
||||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], true, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.seqTag, tagLib, item.seqAnchor)
|
||||
writeTagAndAnchor(target, item.seqProperties, tagLib)
|
||||
indentation += options.indentationStep
|
||||
|
||||
if nextState == dFlowSequenceStart: target.safeWrite('[')
|
||||
|
@ -609,7 +607,6 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
"Cannot have map as map key in JSON output!")
|
||||
nextState = dFlowMapStart
|
||||
of psBlockOnly:
|
||||
yAssert(not s.finished())
|
||||
let next = s.peek()
|
||||
if next.kind == yamlEndMap: nextState = dFlowMapStart
|
||||
else: nextState = dBlockMapValue
|
||||
|
@ -617,16 +614,16 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
case nextState
|
||||
of dBlockMapValue:
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.mapTag, tagLib, item.mapAnchor)
|
||||
writeTagAndAnchor(target, item.mapProperties, tagLib)
|
||||
else:
|
||||
if options.style != psJson:
|
||||
target.safeWrite(newline)
|
||||
writeTagAndAnchor(target, item.mapTag, tagLib, item.mapAnchor)
|
||||
writeTagAndAnchor(target, item.mapProperties, tagLib)
|
||||
indentation += options.indentationStep
|
||||
of dFlowMapStart:
|
||||
target.safeWrite(newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.mapTag, tagLib, item.mapAnchor)
|
||||
writeTagAndAnchor(target, item.mapProperties, tagLib)
|
||||
indentation += options.indentationStep
|
||||
of dBlockInlineMap: discard
|
||||
else: internalError("Invalid nextState: " & $nextState)
|
||||
|
@ -635,12 +632,12 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], true, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.mapTag, tagLib, item.mapAnchor)
|
||||
writeTagAndAnchor(target, item.mapProperties, tagLib)
|
||||
else:
|
||||
startItem(target, options.style, indentation,
|
||||
levels[levels.high], true, newline)
|
||||
if options.style != psJson:
|
||||
writeTagAndAnchor(target, item.mapTag, tagLib, item.mapAnchor)
|
||||
writeTagAndAnchor(target, item.mapProperties, tagLib)
|
||||
indentation += options.indentationStep
|
||||
|
||||
if nextState == dFlowMapStart: target.safeWrite('{')
|
||||
|
@ -711,11 +708,7 @@ proc doPresent(s: var YamlStream, target: PresenterTarget,
|
|||
else: internalError("Invalid level: " & $level)
|
||||
indentation -= options.indentationStep
|
||||
of yamlEndDoc:
|
||||
if finished(s): break
|
||||
if options.style == psJson:
|
||||
raise newException(YamlPresenterJsonError,
|
||||
"Cannot output more than one document in JSON style")
|
||||
target.safeWrite("..." & newline)
|
||||
firstDoc = false
|
||||
|
||||
proc present*(s: var YamlStream, target: Stream,
|
||||
tagLib: TagLibrary,
|
||||
|
|
|
@ -51,3 +51,14 @@ proc yamlTestSuiteEscape*(s: string): string =
|
|||
of '\b': result.add("\\b")
|
||||
of '\t': result.add("\\t")
|
||||
else: result.add(c)
|
||||
|
||||
proc nextAnchor*(s: var string, i: int) =
|
||||
if s[i] == 'z':
|
||||
s[i] = 'a'
|
||||
if i == 0:
|
||||
s.add('a')
|
||||
else:
|
||||
s[i] = 'a'
|
||||
nextAnchor(s, i - 1)
|
||||
else:
|
||||
inc(s[i])
|
|
@ -17,7 +17,7 @@
|
|||
## information.
|
||||
|
||||
import tables, typetraits, strutils, macros, streams, times, parseutils, options
|
||||
import parser, taglib, presenter, stream, private/internal, hints, annotations
|
||||
import data, parser, taglib, presenter, stream, private/internal, hints, annotations
|
||||
export stream, macros, annotations, options
|
||||
# *something* in here needs externally visible `==`(x,y: AnchorId),
|
||||
# but I cannot figure out what. binding it would be the better option.
|
||||
|
@ -26,15 +26,15 @@ type
|
|||
SerializationContext* = ref object
|
||||
## Context information for the process of serializing YAML from Nim values.
|
||||
when not defined(JS):
|
||||
refs*: Table[pointer, AnchorId] # `pointer` does not work with JS
|
||||
refs*: Table[pointer, Anchor] # `pointer` does not work with JS
|
||||
style: AnchorStyle
|
||||
nextAnchorId*: AnchorId
|
||||
put*: proc(e: YamlStreamEvent) {.raises: [], closure.}
|
||||
nextAnchorId*: string
|
||||
put*: proc(e: Event) {.raises: [], closure.}
|
||||
|
||||
ConstructionContext* = ref object
|
||||
## Context information for the process of constructing Nim values from YAML.
|
||||
when not defined(JS):
|
||||
refs*: Table[AnchorId, pointer]
|
||||
refs*: Table[Anchor, pointer]
|
||||
|
||||
YamlConstructionError* = object of YamlLoadingError
|
||||
## Exception that may be raised when constructing data objects from a
|
||||
|
@ -91,16 +91,16 @@ proc newConstructionContext*(): ConstructionContext =
|
|||
when defined(JS):
|
||||
{.emit: [result, """.refs = new Map();"""].}
|
||||
else:
|
||||
result.refs = initTable[AnchorId, pointer]()
|
||||
result.refs = initTable[Anchor, pointer]()
|
||||
|
||||
proc newSerializationContext*(s: AnchorStyle,
|
||||
putImpl: proc(e: YamlStreamEvent) {.raises: [], closure.}):
|
||||
putImpl: proc(e: Event) {.raises: [], closure.}):
|
||||
SerializationContext =
|
||||
result = SerializationContext(style: s, nextAnchorId: 0.AnchorId,
|
||||
result = SerializationContext(style: s, nextAnchorId: "a",
|
||||
put: putImpl)
|
||||
when defined(JS):
|
||||
{.emit: [result, """.refs = new Map();"""].}
|
||||
else: result.refs = initTable[pointer, AnchorId]()
|
||||
else: result.refs = initTable[pointer, Anchor]()
|
||||
|
||||
template presentTag*(t: typedesc, ts: TagStyle): TagId =
|
||||
## Get the TagId that represents the given type in the given style
|
||||
|
@ -127,15 +127,15 @@ proc safeTagUri(id: TagId): string {.raises: [].} =
|
|||
|
||||
proc constructionError(s: YamlStream, msg: string): ref YamlConstructionError =
|
||||
result = newException(YamlConstructionError, msg)
|
||||
if not s.getLastTokenContext(result.line, result.column, result.lineContent):
|
||||
(result.line, result.column) = (-1, -1)
|
||||
if not s.getLastTokenContext(result.mark.line, result.mark.column, result.lineContent):
|
||||
(result.mark.line, result.mark.column) = (-1, -1)
|
||||
result.lineContent = ""
|
||||
|
||||
template constructScalarItem*(s: var YamlStream, i: untyped,
|
||||
t: typedesc, content: untyped) =
|
||||
## Helper template for implementing ``constructObject`` for types that
|
||||
## are constructed from a scalar. ``i`` is the identifier that holds
|
||||
## the scalar as ``YamlStreamEvent`` in the content. Exceptions raised in
|
||||
## the scalar as ``Event`` in the content. Exceptions raised in
|
||||
## the content will be automatically catched and wrapped in
|
||||
## ``YamlConstructionError``, which will then be raised.
|
||||
bind constructionError
|
||||
|
@ -225,11 +225,11 @@ proc representObject*(value: int, tagStyle: TagStyle,
|
|||
c: SerializationContext, tag: TagId)
|
||||
{.raises: [YamlStreamError], inline.}=
|
||||
## represent an integer of architecture-defined length by casting it to int32.
|
||||
## on 64-bit systems, this may cause a RangeError.
|
||||
## on 64-bit systems, this may cause a RangeDefect.
|
||||
|
||||
# currently, sizeof(int) is at least sizeof(int32).
|
||||
try: c.put(scalarEvent($int32(value), tag, yAnchorNone))
|
||||
except RangeError:
|
||||
except RangeDefect:
|
||||
var e = newException(YamlStreamError, getCurrentExceptionMsg())
|
||||
e.parent = getCurrentException()
|
||||
raise e
|
||||
|
@ -272,9 +272,9 @@ proc representObject*[T: uint8|uint16|uint32|uint64](value: T, ts: TagStyle,
|
|||
proc representObject*(value: uint, ts: TagStyle, c: SerializationContext,
|
||||
tag: TagId) {.raises: [YamlStreamError], inline.} =
|
||||
## represent an unsigned integer of architecture-defined length by casting it
|
||||
## to int32. on 64-bit systems, this may cause a RangeError.
|
||||
## to int32. on 64-bit systems, this may cause a RangeDefect.
|
||||
try: c.put(scalarEvent($uint32(value), tag, yAnchorNone))
|
||||
except RangeError:
|
||||
except RangeDefect:
|
||||
var e = newException(YamlStreamError, getCurrentExceptionMsg())
|
||||
e.parent = getCurrentException()
|
||||
raise e
|
||||
|
@ -1174,10 +1174,10 @@ proc constructChild*(s: var YamlStream, c: ConstructionContext,
|
|||
result: var string) =
|
||||
let item = s.peek()
|
||||
if item.kind == yamlScalar:
|
||||
if item.scalarTag notin
|
||||
if item.scalarProperties.tag notin
|
||||
[yTagQuestionMark, yTagExclamationMark, yamlTag(string)]:
|
||||
raise s.constructionError("Wrong tag for string")
|
||||
elif item.scalarAnchor != yAnchorNone:
|
||||
elif item.scalarProperties.anchor != yAnchorNone:
|
||||
raise s.constructionError("Anchor on non-ref type")
|
||||
constructObject(s, c, result)
|
||||
|
||||
|
@ -1238,7 +1238,7 @@ proc constructChild*[O](s: var YamlStream, c: ConstructionContext,
|
|||
discard s.next()
|
||||
return
|
||||
new(result)
|
||||
template removeAnchor(anchor: var AnchorId) {.dirty.} =
|
||||
template removeAnchor(anchor: var Anchor) {.dirty.} =
|
||||
if anchor != yAnchorNone:
|
||||
when defined(JS):
|
||||
{.emit: [c, """.refs.set(""", anchor, """, """, result, """);"""].}
|
||||
|
@ -1278,7 +1278,7 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext) =
|
|||
if isNil(value): c.put(scalarEvent("~", yTagNull))
|
||||
elif c.style == asNone: representChild(value[], ts, c)
|
||||
else:
|
||||
var val: AnchorId
|
||||
var val: Anchor
|
||||
when defined(JS):
|
||||
{.emit: ["""
|
||||
if (""", c, """.refs.has(""", value, """) {
|
||||
|
@ -1286,7 +1286,7 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext) =
|
|||
if (val == """, yAnchorNone, ") {"].}
|
||||
val = c.nextAnchorId
|
||||
{.emit: [c, """.refs.set(""", value, """, """, val, """);"""].}
|
||||
c.nextAnchorId = AnchorId(int(c.nextAnchorId) + 1)
|
||||
nextAnchor(c, len(c.nextAnchorId) - 1)
|
||||
{.emit: "}".}
|
||||
c.put(aliasEvent(val))
|
||||
return
|
||||
|
@ -1297,7 +1297,7 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext) =
|
|||
if val == yAnchorNone:
|
||||
val = c.nextAnchorId
|
||||
c.refs[p] = val
|
||||
c.nextAnchorId = AnchorId(int(c.nextAnchorId) + 1)
|
||||
nextAnchor(c, len(c.nextAnchorId) - 1)
|
||||
c.put(aliasEvent(val))
|
||||
return
|
||||
if c.style == asAlways:
|
||||
|
@ -1305,13 +1305,13 @@ proc representChild*[O](value: ref O, ts: TagStyle, c: SerializationContext) =
|
|||
when defined(JS):
|
||||
{.emit: [c, ".refs.set(", p, ", ", val, ");"].}
|
||||
else: c.refs[p] = val
|
||||
c.nextAnchorId = AnchorId(int(val) + 1)
|
||||
nextAnchor(c, len(c.nextAnchorId) - 1)
|
||||
else: c.refs[p] = yAnchorNone
|
||||
let
|
||||
a = if c.style == asAlways: val else: cast[AnchorId](p)
|
||||
a = if c.style == asAlways: val else: cast[Anchor](p)
|
||||
childTagStyle = if ts == tsAll: tsAll else: tsRootOnly
|
||||
origPut = c.put
|
||||
c.put = proc(e: YamlStreamEvent) =
|
||||
c.put = proc(e: Event) =
|
||||
var ex = e
|
||||
case ex.kind
|
||||
of yamlStartMap:
|
||||
|
@ -1409,7 +1409,7 @@ proc loadMultiDoc*[K](input: Stream | string, target: var seq[K]) =
|
|||
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
|
||||
else: internalError("Unexpected exception: " & $e.parent.name)
|
||||
|
||||
proc setAnchor(a: var AnchorId, c: var SerializationContext)
|
||||
proc setAnchor(a: var Anchor, c: var SerializationContext)
|
||||
{.inline.} =
|
||||
if a != yAnchorNone:
|
||||
when defined(JS):
|
||||
|
@ -1421,7 +1421,7 @@ proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
|||
a: AnchorStyle = asTidy): YamlStream =
|
||||
## Represents a Nim value as ``YamlStream``
|
||||
var bys = newBufferYamlStream()
|
||||
var context = newSerializationContext(a, proc(e: YamlStreamEvent) =
|
||||
var context = newSerializationContext(a, proc(e: Event) =
|
||||
bys.put(e)
|
||||
)
|
||||
bys.put(startDocEvent())
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
## structures provided by Nim's stdlib.
|
||||
|
||||
import json, streams, strutils, tables
|
||||
import taglib, hints, serialization, stream, private/internal, parser
|
||||
import data, taglib, hints, serialization, stream, private/internal, parser
|
||||
|
||||
# represents a single YAML level. The `node` with name `key`.
|
||||
# `expKey` is used to indicate that an empty node shall be filled
|
||||
|
@ -102,8 +102,8 @@ proc constructJson*(s: var YamlStream): seq[JsonNode]
|
|||
result.add(levels.pop().node)
|
||||
of yamlStartSeq:
|
||||
levels.add(initLevel(newJArray()))
|
||||
if event.seqAnchor != yAnchorNone:
|
||||
anchors[event.seqAnchor] = levels[levels.high].node
|
||||
if event.seqProperties.anchor != yAnchorNone:
|
||||
anchors[event.seqProperties.anchor] = levels[levels.high].node
|
||||
of yamlStartMap:
|
||||
levels.add(initLevel(newJObject()))
|
||||
if event.mapAnchor != yAnchorNone:
|
||||
|
|
Loading…
Reference in New Issue