mirror of https://github.com/status-im/NimYAML.git
Various code style and naming fixes
* Renamed some symbols for consistency, fixes #6: - yamlStartSequence -> yamlStartSeq - yamlEndSequence -> yamlEndSeq - yamlStartDocument -> yamlStartDoc - yamlEndDocument -> yamlEndDoc - yTagMap -> yTagMapping * Improved code formatting at some places * Fixed code documentation at some places * Added generic objects to TODO list * Removed obsolete parsing tests, these are superseeded by yaml-dev-kit test suite integration
This commit is contained in:
parent
2e8d7b39ab
commit
16d1a1bceb
|
@ -12,6 +12,7 @@ an overview of already available features.
|
||||||
- Support for more standard library types
|
- Support for more standard library types
|
||||||
- Support polymorphism
|
- Support polymorphism
|
||||||
- Support variant objects
|
- Support variant objects
|
||||||
|
- Support generic objects
|
||||||
- Support transient fields (i.e. fields that will not be (de-)serialized on
|
- Support transient fields (i.e. fields that will not be (de-)serialized on
|
||||||
objects and tuples)
|
objects and tuples)
|
||||||
- Check for and avoid name clashes when generating local tags for custom
|
- Check for and avoid name clashes when generating local tags for custom
|
||||||
|
@ -20,8 +21,8 @@ an overview of already available features.
|
||||||
## Developers
|
## Developers
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nim tests # runs all tests
|
nim tests # runs unit tests (serialization, dom, json)
|
||||||
nim parserTests # runs parser tests
|
# for parser tests, see yamlTestSuite
|
||||||
nim serializationTests # runs serialization tests
|
nim serializationTests # runs serialization tests
|
||||||
nim documentation # builds documentation to folder docout
|
nim documentation # builds documentation to folder docout
|
||||||
nim server # builds the REST server used for the testing ground
|
nim server # builds the REST server used for the testing ground
|
||||||
|
|
|
@ -13,11 +13,6 @@ task yamlTestSuite, "Run YAML 1.2 test suite":
|
||||||
--verbosity:0
|
--verbosity:0
|
||||||
setCommand "c", "test/yamlTestSuite"
|
setCommand "c", "test/yamlTestSuite"
|
||||||
|
|
||||||
task parserTests, "Run parser tests":
|
|
||||||
--r
|
|
||||||
--verbosity:0
|
|
||||||
setCommand "c", "test/parsing"
|
|
||||||
|
|
||||||
task serializationTests, "Run serialization tests":
|
task serializationTests, "Run serialization tests":
|
||||||
--r
|
--r
|
||||||
--verbosity:0
|
--verbosity:0
|
||||||
|
|
|
@ -47,11 +47,11 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
||||||
if start.mapAnchor != yAnchorNone:
|
if start.mapAnchor != yAnchorNone:
|
||||||
assert(not c.refs.hasKey(start.mapAnchor))
|
assert(not c.refs.hasKey(start.mapAnchor))
|
||||||
c.refs[start.mapAnchor] = cast[pointer](result)
|
c.refs[start.mapAnchor] = cast[pointer](result)
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
result.tag = tagLib.uri(start.seqTag)
|
result.tag = tagLib.uri(start.seqTag)
|
||||||
result.kind = ySequence
|
result.kind = ySequence
|
||||||
result.children = newSeq[YamlNode]()
|
result.children = newSeq[YamlNode]()
|
||||||
while s.peek().kind != yamlEndSequence:
|
while s.peek().kind != yamlEndSeq:
|
||||||
result.children.add(composeNode(s, tagLib, c))
|
result.children.add(composeNode(s, tagLib, c))
|
||||||
if start.seqAnchor != yAnchorNone:
|
if start.seqAnchor != yAnchorNone:
|
||||||
assert(not c.refs.hasKey(start.seqAnchor))
|
assert(not c.refs.hasKey(start.seqAnchor))
|
||||||
|
@ -74,9 +74,9 @@ proc composeNode(s: var YamlStream, tagLib: TagLibrary,
|
||||||
proc compose*(s: var YamlStream, tagLib: TagLibrary): YamlDocument
|
proc compose*(s: var YamlStream, tagLib: TagLibrary): YamlDocument
|
||||||
{.raises: [YamlStreamError, YamlConstructionError].} =
|
{.raises: [YamlStreamError, YamlConstructionError].} =
|
||||||
var context = newConstructionContext()
|
var context = newConstructionContext()
|
||||||
assert s.next().kind == yamlStartDocument
|
assert s.next().kind == yamlStartDoc, "Malformed YamlStream"
|
||||||
result.root = composeNode(s, tagLib, context)
|
result.root = composeNode(s, tagLib, context)
|
||||||
assert s.next().kind == yamlEndDocument
|
assert s.next().kind == yamlEndDoc, "Malformed YamlStream"
|
||||||
|
|
||||||
proc loadDOM*(s: Stream): YamlDocument
|
proc loadDOM*(s: Stream): YamlDocument
|
||||||
{.raises: [IOError, YamlParserError, YamlConstructionError].} =
|
{.raises: [IOError, YamlParserError, YamlConstructionError].} =
|
||||||
|
@ -126,8 +126,7 @@ proc serializeNode(n: YamlNode, c: SerializationContext, a: AnchorStyle,
|
||||||
except KeyError: assert false, "Can never happen"
|
except KeyError: assert false, "Can never happen"
|
||||||
result = iterator(): YamlStreamEvent =
|
result = iterator(): YamlStreamEvent =
|
||||||
case n.kind
|
case n.kind
|
||||||
of yScalar:
|
of yScalar: yield scalarEvent(n.content, tagId, anchor)
|
||||||
yield scalarEvent(n.content, tagId, anchor)
|
|
||||||
of ySequence:
|
of ySequence:
|
||||||
yield startSeqEvent(tagId, anchor)
|
yield startSeqEvent(tagId, anchor)
|
||||||
for item in n.children:
|
for item in n.children:
|
||||||
|
@ -155,8 +154,7 @@ proc serializeNode(n: YamlNode, c: SerializationContext, a: AnchorStyle,
|
||||||
template processAnchoredEvent(target: expr, c: SerializationContext): stmt =
|
template processAnchoredEvent(target: expr, c: SerializationContext): stmt =
|
||||||
try:
|
try:
|
||||||
let anchorId = c.refs[cast[pointer](target)]
|
let anchorId = c.refs[cast[pointer](target)]
|
||||||
if anchorId != yAnchorNone:
|
if anchorId != yAnchorNone: target = anchorId
|
||||||
target = anchorId
|
|
||||||
else: target = yAnchorNone
|
else: target = yAnchorNone
|
||||||
except KeyError: assert false, "Can never happen"
|
except KeyError: assert false, "Can never happen"
|
||||||
yield event
|
yield event
|
||||||
|
@ -179,7 +177,7 @@ proc serialize*(doc: YamlDocument, tagLib: TagLibrary, a: AnchorStyle = asTidy):
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
processAnchoredEvent(event.scalarAnchor, context)
|
processAnchoredEvent(event.scalarAnchor, context)
|
||||||
of yamlStartMap: processAnchoredEvent(event.mapAnchor, context)
|
of yamlStartMap: processAnchoredEvent(event.mapAnchor, context)
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
processAnchoredEvent(event.seqAnchor, context)
|
processAnchoredEvent(event.seqAnchor, context)
|
||||||
else: yield event
|
else: yield event
|
||||||
yield endDocEvent()
|
yield endDocEvent()
|
||||||
|
|
|
@ -8,12 +8,12 @@ proc `==`*(left: YamlStreamEvent, right: YamlStreamEvent): bool =
|
||||||
if left.kind != right.kind:
|
if left.kind != right.kind:
|
||||||
return false
|
return false
|
||||||
case left.kind
|
case left.kind
|
||||||
of yamlStartDocument, yamlEndDocument, yamlEndMap, yamlEndSequence:
|
of yamlStartDoc, yamlEndDoc, yamlEndMap, yamlEndSeq:
|
||||||
result = true
|
result = true
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
result = left.mapAnchor == right.mapAnchor and
|
result = left.mapAnchor == right.mapAnchor and
|
||||||
left.mapTag == right.mapTag
|
left.mapTag == right.mapTag
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
result = left.seqAnchor == right.seqAnchor and
|
result = left.seqAnchor == right.seqAnchor and
|
||||||
left.seqTag == right.seqTag
|
left.seqTag == right.seqTag
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
|
@ -26,13 +26,13 @@ proc `==`*(left: YamlStreamEvent, right: YamlStreamEvent): bool =
|
||||||
proc `$`*(event: YamlStreamEvent): string =
|
proc `$`*(event: YamlStreamEvent): string =
|
||||||
result = $event.kind & '('
|
result = $event.kind & '('
|
||||||
case event.kind
|
case event.kind
|
||||||
of yamlEndMap, yamlEndSequence, yamlStartDocument, yamlEndDocument:
|
of yamlEndMap, yamlEndSeq, yamlStartDoc, yamlEndDoc:
|
||||||
discard
|
discard
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
result &= "tag=" & $event.mapTag
|
result &= "tag=" & $event.mapTag
|
||||||
if event.mapAnchor != yAnchorNone:
|
if event.mapAnchor != yAnchorNone:
|
||||||
result &= ", anchor=" & $event.mapAnchor
|
result &= ", anchor=" & $event.mapAnchor
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
result &= "tag=" & $event.seqTag
|
result &= "tag=" & $event.seqTag
|
||||||
if event.seqAnchor != yAnchorNone:
|
if event.seqAnchor != yAnchorNone:
|
||||||
result &= ", anchor=" & $event.seqAnchor
|
result &= ", anchor=" & $event.seqAnchor
|
||||||
|
@ -46,10 +46,10 @@ proc `$`*(event: YamlStreamEvent): string =
|
||||||
result &= ")"
|
result &= ")"
|
||||||
|
|
||||||
proc startDocEvent*(): YamlStreamEvent =
|
proc startDocEvent*(): YamlStreamEvent =
|
||||||
result = YamlStreamEvent(kind: yamlStartDocument)
|
result = YamlStreamEvent(kind: yamlStartDoc)
|
||||||
|
|
||||||
proc endDocEvent*(): YamlStreamEvent =
|
proc endDocEvent*(): YamlStreamEvent =
|
||||||
result = YamlStreamEvent(kind: yamlEndDocument)
|
result = YamlStreamEvent(kind: yamlEndDoc)
|
||||||
|
|
||||||
proc startMapEvent*(tag: TagId = yTagQuestionMark,
|
proc startMapEvent*(tag: TagId = yTagQuestionMark,
|
||||||
anchor: AnchorId = yAnchorNone): YamlStreamEvent =
|
anchor: AnchorId = yAnchorNone): YamlStreamEvent =
|
||||||
|
@ -60,11 +60,11 @@ proc endMapEvent*(): YamlStreamEvent =
|
||||||
|
|
||||||
proc startSeqEvent*(tag: TagId = yTagQuestionMark,
|
proc startSeqEvent*(tag: TagId = yTagQuestionMark,
|
||||||
anchor: AnchorId = yAnchorNone): YamlStreamEvent =
|
anchor: AnchorId = yAnchorNone): YamlStreamEvent =
|
||||||
result = YamlStreamEvent(kind: yamlStartSequence, seqTag: tag,
|
result = YamlStreamEvent(kind: yamlStartSeq, seqTag: tag,
|
||||||
seqAnchor: anchor)
|
seqAnchor: anchor)
|
||||||
|
|
||||||
proc endSeqEvent*(): YamlStreamEvent =
|
proc endSeqEvent*(): YamlStreamEvent =
|
||||||
result = YamlStreamEvent(kind: yamlEndSequence)
|
result = YamlStreamEvent(kind: yamlEndSeq)
|
||||||
|
|
||||||
proc scalarEvent*(content: string = "", tag: TagId = yTagQuestionMark,
|
proc scalarEvent*(content: string = "", tag: TagId = yTagQuestionMark,
|
||||||
anchor: AnchorId = yAnchorNone): YamlStreamEvent =
|
anchor: AnchorId = yAnchorNone): YamlStreamEvent =
|
||||||
|
|
|
@ -169,7 +169,7 @@ template handleBlockSequenceIndicator() {.dirty.} =
|
||||||
startToken()
|
startToken()
|
||||||
case level.kind
|
case level.kind
|
||||||
of fplUnknown:
|
of fplUnknown:
|
||||||
handleObjectStart(yamlStartSequence)
|
handleObjectStart(yamlStartSeq)
|
||||||
of fplSequence:
|
of fplSequence:
|
||||||
if level.indentation != indentation:
|
if level.indentation != indentation:
|
||||||
parserError("Invalid indentation of block sequence indicator")
|
parserError("Invalid indentation of block sequence indicator")
|
||||||
|
@ -1443,7 +1443,7 @@ proc parse*(p: YamlParser, s: Stream): YamlStream =
|
||||||
p.lexer.bufpos.inc()
|
p.lexer.bufpos.inc()
|
||||||
explicitFlowKey = false
|
explicitFlowKey = false
|
||||||
of '[':
|
of '[':
|
||||||
handleObjectStart(yamlStartSequence)
|
handleObjectStart(yamlStartSeq)
|
||||||
flowdepth.inc()
|
flowdepth.inc()
|
||||||
p.lexer.bufpos.inc()
|
p.lexer.bufpos.inc()
|
||||||
of '}':
|
of '}':
|
||||||
|
|
|
@ -86,14 +86,14 @@ proc constructJson*(s: var YamlStream): seq[JsonNode] =
|
||||||
anchors = initTable[AnchorId, JsonNode]()
|
anchors = initTable[AnchorId, JsonNode]()
|
||||||
for event in s:
|
for event in s:
|
||||||
case event.kind
|
case event.kind
|
||||||
of yamlStartDocument:
|
of yamlStartDoc:
|
||||||
# we don't need to do anything here; root node will be created
|
# we don't need to do anything here; root node will be created
|
||||||
# by first scalar, sequence or map event
|
# by first scalar, sequence or map event
|
||||||
discard
|
discard
|
||||||
of yamlEndDocument:
|
of yamlEndDoc:
|
||||||
# we can savely assume that levels has e length of exactly 1.
|
# we can savely assume that levels has e length of exactly 1.
|
||||||
result.add(levels.pop().node)
|
result.add(levels.pop().node)
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
levels.add(initLevel(newJArray()))
|
levels.add(initLevel(newJArray()))
|
||||||
if event.seqAnchor != yAnchorNone:
|
if event.seqAnchor != yAnchorNone:
|
||||||
anchors[event.seqAnchor] = levels[levels.high].node
|
anchors[event.seqAnchor] = levels[levels.high].node
|
||||||
|
@ -130,9 +130,8 @@ proc constructJson*(s: var YamlStream): seq[JsonNode] =
|
||||||
levels[levels.high].key = nil
|
levels[levels.high].key = nil
|
||||||
if event.scalarAnchor != yAnchorNone:
|
if event.scalarAnchor != yAnchorNone:
|
||||||
anchors[event.scalarAnchor] = jsonScalar
|
anchors[event.scalarAnchor] = jsonScalar
|
||||||
else:
|
else: discard # will never happen
|
||||||
discard # will never happen
|
of yamlEndSeq, yamlEndMap:
|
||||||
of yamlEndSequence, yamlEndMap:
|
|
||||||
if levels.len > 1:
|
if levels.len > 1:
|
||||||
let level = levels.pop()
|
let level = levels.pop()
|
||||||
case levels[levels.high].node.kind
|
case levels[levels.high].node.kind
|
||||||
|
@ -146,10 +145,8 @@ proc constructJson*(s: var YamlStream): seq[JsonNode] =
|
||||||
levels[levels.high].node[
|
levels[levels.high].node[
|
||||||
levels[levels.high].key] = level.node
|
levels[levels.high].key] = level.node
|
||||||
levels[levels.high].key = nil
|
levels[levels.high].key = nil
|
||||||
else:
|
else: discard # will never happen
|
||||||
discard # will never happen
|
else: discard # wait for yamlEndDocument
|
||||||
else:
|
|
||||||
discard # wait for yamlEndDocument
|
|
||||||
of yamlAlias:
|
of yamlAlias:
|
||||||
# we can savely assume that the alias exists in anchors
|
# we can savely assume that the alias exists in anchors
|
||||||
# (else the parser would have already thrown an exception)
|
# (else the parser would have already thrown an exception)
|
||||||
|
@ -176,8 +173,7 @@ proc constructJson*(s: var YamlStream): seq[JsonNode] =
|
||||||
# have resulted in a parser error earlier.
|
# have resulted in a parser error earlier.
|
||||||
assert(false)
|
assert(false)
|
||||||
levels[levels.high].key = nil
|
levels[levels.high].key = nil
|
||||||
else:
|
else: discard # will never happen
|
||||||
discard # will never happen
|
|
||||||
|
|
||||||
proc loadToJson*(s: Stream): seq[JsonNode] =
|
proc loadToJson*(s: Stream): seq[JsonNode] =
|
||||||
var
|
var
|
||||||
|
|
|
@ -345,7 +345,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
while cached.len > 0 or not s.finished():
|
while cached.len > 0 or not s.finished():
|
||||||
let item = if cached.len > 0: cached.dequeue else: s.next()
|
let item = if cached.len > 0: cached.dequeue else: s.next()
|
||||||
case item.kind
|
case item.kind
|
||||||
of yamlStartDocument:
|
of yamlStartDoc:
|
||||||
if options.style != psJson:
|
if options.style != psJson:
|
||||||
# TODO: tag directives
|
# TODO: tag directives
|
||||||
try:
|
try:
|
||||||
|
@ -390,8 +390,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
elif item.scalarTag in [yTagQuestionMark, yTagFloat] and
|
elif item.scalarTag in [yTagQuestionMark, yTagFloat] and
|
||||||
hint == yTypeFloat:
|
hint == yTypeFloat:
|
||||||
safeWrite(item.scalarContent)
|
safeWrite(item.scalarContent)
|
||||||
else:
|
else: writeDoubleQuotedJson(item.scalarContent, target)
|
||||||
writeDoubleQuotedJson(item.scalarContent, target)
|
|
||||||
elif options.style == psCanonical:
|
elif options.style == psCanonical:
|
||||||
writeDoubleQuoted(item.scalarContent, target,
|
writeDoubleQuoted(item.scalarContent, target,
|
||||||
indentation + options.indentationStep,
|
indentation + options.indentationStep,
|
||||||
|
@ -421,7 +420,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
var e = newException(YamlPresenterOutputError, "")
|
var e = newException(YamlPresenterOutputError, "")
|
||||||
e.parent = getCurrentException()
|
e.parent = getCurrentException()
|
||||||
raise e
|
raise e
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
var nextState: DumperState
|
var nextState: DumperState
|
||||||
case options.style
|
case options.style
|
||||||
of psDefault:
|
of psDefault:
|
||||||
|
@ -431,12 +430,9 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
let next = s.next()
|
let next = s.next()
|
||||||
cached.enqueue(next)
|
cached.enqueue(next)
|
||||||
case next.kind
|
case next.kind
|
||||||
of yamlScalar:
|
of yamlScalar: length += 2 + next.scalarContent.len
|
||||||
length += 2 + next.scalarContent.len
|
of yamlAlias: length += 6
|
||||||
of yamlAlias:
|
of yamlEndSeq: break
|
||||||
length += 6
|
|
||||||
of yamlEndSequence:
|
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
length = high(int)
|
length = high(int)
|
||||||
break
|
break
|
||||||
|
@ -472,8 +468,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
item.seqTag, tagLib, item.seqAnchor)
|
item.seqTag, tagLib, item.seqAnchor)
|
||||||
indentation += options.indentationStep
|
indentation += options.indentationStep
|
||||||
|
|
||||||
if nextState == dFlowSequenceStart:
|
if nextState == dFlowSequenceStart: safeWrite('[')
|
||||||
safeWrite('[')
|
|
||||||
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
||||||
levels[levels.high] in
|
levels[levels.high] in
|
||||||
[dBlockExplicitMapKey, dBlockMapValue,
|
[dBlockExplicitMapKey, dBlockMapValue,
|
||||||
|
@ -500,18 +495,15 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
mps = mpNeedBlock
|
mps = mpNeedBlock
|
||||||
nextState = if mps == mpNeedBlock: dBlockMapValue else:
|
nextState = if mps == mpNeedBlock: dBlockMapValue else:
|
||||||
dBlockInlineMap
|
dBlockInlineMap
|
||||||
of psMinimal:
|
of psMinimal: nextState = dFlowMapStart
|
||||||
nextState = dFlowMapStart
|
of psCanonical: nextState = dFlowMapStart
|
||||||
of psCanonical:
|
|
||||||
nextState = dFlowMapStart
|
|
||||||
of psJson:
|
of psJson:
|
||||||
if levels.len > 0 and levels[levels.high] in
|
if levels.len > 0 and levels[levels.high] in
|
||||||
[dFlowMapStart, dFlowMapValue]:
|
[dFlowMapStart, dFlowMapValue]:
|
||||||
raise newException(YamlPresenterJsonError,
|
raise newException(YamlPresenterJsonError,
|
||||||
"Cannot have map as map key in JSON output!")
|
"Cannot have map as map key in JSON output!")
|
||||||
nextState = dFlowMapStart
|
nextState = dFlowMapStart
|
||||||
of psBlockOnly:
|
of psBlockOnly: nextState = dBlockMapValue
|
||||||
nextState = dBlockMapValue
|
|
||||||
if levels.len == 0:
|
if levels.len == 0:
|
||||||
if nextState == dBlockMapValue:
|
if nextState == dBlockMapValue:
|
||||||
if options.style != psJson:
|
if options.style != psJson:
|
||||||
|
@ -538,8 +530,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
item.mapTag, tagLib, item.mapAnchor)
|
item.mapTag, tagLib, item.mapAnchor)
|
||||||
indentation += options.indentationStep
|
indentation += options.indentationStep
|
||||||
|
|
||||||
if nextState == dFlowMapStart:
|
if nextState == dFlowMapStart: safeWrite('{')
|
||||||
safeWrite('{')
|
|
||||||
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
if levels.len > 0 and options.style in [psJson, psCanonical] and
|
||||||
levels[levels.high] in
|
levels[levels.high] in
|
||||||
[dBlockExplicitMapKey, dBlockMapValue,
|
[dBlockExplicitMapKey, dBlockMapValue,
|
||||||
|
@ -547,13 +538,12 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
indentation += options.indentationStep
|
indentation += options.indentationStep
|
||||||
levels.add(nextState)
|
levels.add(nextState)
|
||||||
|
|
||||||
of yamlEndSequence:
|
of yamlEndSeq:
|
||||||
assert levels.len > 0
|
assert levels.len > 0
|
||||||
case levels.pop()
|
case levels.pop()
|
||||||
of dFlowSequenceItem:
|
of dFlowSequenceItem:
|
||||||
case options.style
|
case options.style
|
||||||
of psDefault, psMinimal, psBlockOnly:
|
of psDefault, psMinimal, psBlockOnly: safeWrite(']')
|
||||||
safeWrite(']')
|
|
||||||
of psJson, psCanonical:
|
of psJson, psCanonical:
|
||||||
indentation -= options.indentationStep
|
indentation -= options.indentationStep
|
||||||
try:
|
try:
|
||||||
|
@ -575,10 +565,8 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||||
indentation -= options.indentationStep
|
indentation -= options.indentationStep
|
||||||
safeWrite(']')
|
safeWrite(']')
|
||||||
of dBlockSequenceItem:
|
of dBlockSequenceItem: discard
|
||||||
discard
|
else: assert false
|
||||||
else:
|
|
||||||
assert false
|
|
||||||
indentation -= options.indentationStep
|
indentation -= options.indentationStep
|
||||||
of yamlEndMap:
|
of yamlEndMap:
|
||||||
assert levels.len > 0
|
assert levels.len > 0
|
||||||
|
@ -586,8 +574,7 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
case level
|
case level
|
||||||
of dFlowMapValue:
|
of dFlowMapValue:
|
||||||
case options.style
|
case options.style
|
||||||
of psDefault, psMinimal, psBlockOnly:
|
of psDefault, psMinimal, psBlockOnly: safeWrite('}')
|
||||||
safeWrite('}')
|
|
||||||
of psJson, psCanonical:
|
of psJson, psCanonical:
|
||||||
indentation -= options.indentationStep
|
indentation -= options.indentationStep
|
||||||
try:
|
try:
|
||||||
|
@ -609,12 +596,10 @@ proc present*(s: var YamlStream, target: Stream, tagLib: TagLibrary,
|
||||||
dBlockImplicitMapKey, dBlockSequenceItem]:
|
dBlockImplicitMapKey, dBlockSequenceItem]:
|
||||||
indentation -= options.indentationStep
|
indentation -= options.indentationStep
|
||||||
safeWrite('}')
|
safeWrite('}')
|
||||||
of dBlockMapValue, dBlockInlineMap:
|
of dBlockMapValue, dBlockInlineMap: discard
|
||||||
discard
|
else: assert false
|
||||||
else:
|
|
||||||
assert false
|
|
||||||
indentation -= options.indentationStep
|
indentation -= options.indentationStep
|
||||||
of yamlEndDocument:
|
of yamlEndDoc:
|
||||||
if finished(s): break
|
if finished(s): break
|
||||||
safeWrite("..." & newline)
|
safeWrite("..." & newline)
|
||||||
|
|
||||||
|
@ -630,14 +615,14 @@ proc transform*(input: Stream, output: Stream,
|
||||||
for e in events:
|
for e in events:
|
||||||
var event = e
|
var event = e
|
||||||
case event.kind
|
case event.kind
|
||||||
of yamlStartDocument, yamlEndDocument, yamlEndMap,
|
of yamlStartDoc, yamlEndDoc, yamlEndMap, yamlAlias,
|
||||||
yamlAlias, yamlEndSequence:
|
yamlEndSeq:
|
||||||
discard
|
discard
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
if event.mapTag in [yTagQuestionMark,
|
if event.mapTag in [yTagQuestionMark,
|
||||||
yTagExclamationMark]:
|
yTagExclamationMark]:
|
||||||
event.mapTag = yTagMap
|
event.mapTag = yTagMapping
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
if event.seqTag in [yTagQuestionMark,
|
if event.seqTag in [yTagQuestionMark,
|
||||||
yTagExclamationMark]:
|
yTagExclamationMark]:
|
||||||
event.seqTag = yTagSequence
|
event.seqTag = yTagSequence
|
||||||
|
|
|
@ -285,10 +285,10 @@ proc constructObject*[T](s: var YamlStream, c: ConstructionContext,
|
||||||
{.raises: [YamlConstructionError, YamlStreamError].} =
|
{.raises: [YamlConstructionError, YamlStreamError].} =
|
||||||
## constructs a Nim seq from a YAML sequence
|
## constructs a Nim seq from a YAML sequence
|
||||||
let event = s.next()
|
let event = s.next()
|
||||||
if event.kind != yamlStartSequence:
|
if event.kind != yamlStartSeq:
|
||||||
raise newException(YamlConstructionError, "Expected sequence start")
|
raise newException(YamlConstructionError, "Expected sequence start")
|
||||||
result = newSeq[T]()
|
result = newSeq[T]()
|
||||||
while s.peek().kind != yamlEndSequence:
|
while s.peek().kind != yamlEndSeq:
|
||||||
var item: T
|
var item: T
|
||||||
constructChild(s, c, item)
|
constructChild(s, c, item)
|
||||||
result.add(item)
|
result.add(item)
|
||||||
|
@ -299,7 +299,7 @@ proc representObject*[T](value: seq[T], ts: TagStyle,
|
||||||
## represents a Nim seq as YAML sequence
|
## represents a Nim seq as YAML sequence
|
||||||
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: yamlStartSeq,
|
||||||
seqTag: presentTag(seq[T], ts),
|
seqTag: presentTag(seq[T], ts),
|
||||||
seqAnchor: yAnchorNone)
|
seqAnchor: yAnchorNone)
|
||||||
for item in value:
|
for item in value:
|
||||||
|
@ -308,7 +308,7 @@ proc representObject*[T](value: seq[T], ts: TagStyle,
|
||||||
let event = events()
|
let event = events()
|
||||||
if finished(events): break
|
if finished(events): break
|
||||||
yield event
|
yield event
|
||||||
yield YamlStreamEvent(kind: yamlEndSequence)
|
yield YamlStreamEvent(kind: yamlEndSeq)
|
||||||
|
|
||||||
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
|
proc yamlTag*[K, V](T: typedesc[Table[K, V]]): TagId {.inline, raises: [].} =
|
||||||
try:
|
try:
|
||||||
|
@ -456,7 +456,7 @@ proc constructChild*[T](s: var YamlStream, c: ConstructionContext,
|
||||||
typetraits.name(T))
|
typetraits.name(T))
|
||||||
elif item.mapAnchor != yAnchorNone:
|
elif item.mapAnchor != yAnchorNone:
|
||||||
raise newException(YamlConstructionError, "Anchor on non-ref type")
|
raise newException(YamlConstructionError, "Anchor on non-ref type")
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
if item.seqTag notin [yTagQuestionMark, yamlTag(T)]:
|
if item.seqTag notin [yTagQuestionMark, yamlTag(T)]:
|
||||||
raise newException(YamlConstructionError, "Wrong tag for " &
|
raise newException(YamlConstructionError, "Wrong tag for " &
|
||||||
typetraits.name(T))
|
typetraits.name(T))
|
||||||
|
@ -492,7 +492,7 @@ proc constructChild*[O](s: var YamlStream, c: ConstructionContext,
|
||||||
case e.kind
|
case e.kind
|
||||||
of yamlScalar: removeAnchor(e.scalarAnchor)
|
of yamlScalar: removeAnchor(e.scalarAnchor)
|
||||||
of yamlStartMap: removeAnchor(e.mapAnchor)
|
of yamlStartMap: removeAnchor(e.mapAnchor)
|
||||||
of yamlStartSequence: removeAnchor(e.seqAnchor)
|
of yamlStartSeq: removeAnchor(e.seqAnchor)
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
s.peek = e
|
s.peek = e
|
||||||
try:
|
try:
|
||||||
|
@ -542,7 +542,7 @@ proc representObject*[O](value: ref O, ts: TagStyle, c: SerializationContext):
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
first.mapAnchor = a
|
first.mapAnchor = a
|
||||||
if ts == tsNone: first.mapTag = yTagQuestionMark
|
if ts == tsNone: first.mapTag = yTagQuestionMark
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
first.seqAnchor = a
|
first.seqAnchor = a
|
||||||
if ts == tsNone: first.seqTag = yTagQuestionMark
|
if ts == tsNone: first.seqTag = yTagQuestionMark
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
|
@ -562,11 +562,11 @@ proc construct*[T](s: var YamlStream, target: var T) =
|
||||||
context = newConstructionContext()
|
context = newConstructionContext()
|
||||||
try:
|
try:
|
||||||
var e = s.next()
|
var e = s.next()
|
||||||
assert(e.kind == yamlStartDocument)
|
assert(e.kind == yamlStartDoc)
|
||||||
|
|
||||||
constructChild(s, context, target)
|
constructChild(s, context, target)
|
||||||
e = s.next()
|
e = s.next()
|
||||||
assert(e.kind == yamlEndDocument)
|
assert(e.kind == yamlEndDoc)
|
||||||
except YamlConstructionError:
|
except YamlConstructionError:
|
||||||
raise (ref YamlConstructionError)(getCurrentException())
|
raise (ref YamlConstructionError)(getCurrentException())
|
||||||
except YamlStreamError:
|
except YamlStreamError:
|
||||||
|
@ -611,13 +611,13 @@ proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
||||||
var
|
var
|
||||||
context = newSerializationContext(a)
|
context = newSerializationContext(a)
|
||||||
objStream = iterator(): YamlStreamEvent =
|
objStream = iterator(): YamlStreamEvent =
|
||||||
yield YamlStreamEvent(kind: yamlStartDocument)
|
yield YamlStreamEvent(kind: yamlStartDoc)
|
||||||
var events = representObject(value, ts, context)
|
var events = representObject(value, ts, context)
|
||||||
while true:
|
while true:
|
||||||
let e = events()
|
let e = events()
|
||||||
if finished(events): break
|
if finished(events): break
|
||||||
yield e
|
yield e
|
||||||
yield YamlStreamEvent(kind: yamlEndDocument)
|
yield YamlStreamEvent(kind: yamlEndDoc)
|
||||||
if a == asTidy:
|
if a == asTidy:
|
||||||
var objQueue = newSeq[YamlStreamEvent]()
|
var objQueue = newSeq[YamlStreamEvent]()
|
||||||
try:
|
try:
|
||||||
|
@ -631,7 +631,7 @@ proc represent*[T](value: T, ts: TagStyle = tsRootOnly,
|
||||||
case event.kind
|
case event.kind
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
event.mapAnchor.setAnchor(context.refs)
|
event.mapAnchor.setAnchor(context.refs)
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
event.seqAnchor.setAnchor(context.refs)
|
event.seqAnchor.setAnchor(context.refs)
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
event.scalarAnchor.setAnchor(context.refs)
|
event.scalarAnchor.setAnchor(context.refs)
|
||||||
|
|
|
@ -10,7 +10,7 @@ proc `$`*(id: TagId): string =
|
||||||
of yTagExclamationMark: "!"
|
of yTagExclamationMark: "!"
|
||||||
of yTagString: "!!str"
|
of yTagString: "!!str"
|
||||||
of yTagSequence: "!!seq"
|
of yTagSequence: "!!seq"
|
||||||
of yTagMap: "!!map"
|
of yTagMapping: "!!map"
|
||||||
of yTagNull: "!!null"
|
of yTagNull: "!!null"
|
||||||
of yTagBoolean: "!!bool"
|
of yTagBoolean: "!!bool"
|
||||||
of yTagInteger: "!!int"
|
of yTagInteger: "!!int"
|
||||||
|
@ -49,7 +49,7 @@ proc initFailsafeTagLibrary(): TagLibrary =
|
||||||
result.tags["?"] = yTagQuestionMark
|
result.tags["?"] = yTagQuestionMark
|
||||||
result.tags["tag:yaml.org,2002:str"] = yTagString
|
result.tags["tag:yaml.org,2002:str"] = yTagString
|
||||||
result.tags["tag:yaml.org,2002:seq"] = yTagSequence
|
result.tags["tag:yaml.org,2002:seq"] = yTagSequence
|
||||||
result.tags["tag:yaml.org,2002:map"] = yTagMap
|
result.tags["tag:yaml.org,2002:map"] = yTagMapping
|
||||||
|
|
||||||
proc initCoreTagLibrary(): TagLibrary =
|
proc initCoreTagLibrary(): TagLibrary =
|
||||||
result = initFailsafeTagLibrary()
|
result = initFailsafeTagLibrary()
|
||||||
|
|
|
@ -33,8 +33,7 @@ proc printDifference*(expected, actual: YamlStreamEvent) =
|
||||||
", got ",
|
", got ",
|
||||||
cast[int](actual.scalarContent[i]), ")"
|
cast[int](actual.scalarContent[i]), ")"
|
||||||
break
|
break
|
||||||
else:
|
else: echo "[scalarEvent] Unknown difference"
|
||||||
echo "[scalarEvent] Unknown difference"
|
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
if expected.mapTag != actual.mapTag:
|
if expected.mapTag != actual.mapTag:
|
||||||
echo "[map.tag] expected ", expected.mapTag, ", got ",
|
echo "[map.tag] expected ", expected.mapTag, ", got ",
|
||||||
|
@ -42,25 +41,21 @@ proc printDifference*(expected, actual: YamlStreamEvent) =
|
||||||
elif expected.mapAnchor != actual.mapAnchor:
|
elif expected.mapAnchor != actual.mapAnchor:
|
||||||
echo "[map.anchor] expected ", expected.mapAnchor, ", got ",
|
echo "[map.anchor] expected ", expected.mapAnchor, ", got ",
|
||||||
actual.mapAnchor
|
actual.mapAnchor
|
||||||
else:
|
else: echo "[map.tag] Unknown difference"
|
||||||
echo "[map.tag] Unknown difference"
|
of yamlStartSeq:
|
||||||
of yamlStartSequence:
|
|
||||||
if expected.seqTag != actual.seqTag:
|
if expected.seqTag != actual.seqTag:
|
||||||
echo "[seq.tag] expected ", expected.seqTag, ", got ",
|
echo "[seq.tag] expected ", expected.seqTag, ", got ",
|
||||||
actual.seqTag
|
actual.seqTag
|
||||||
elif expected.seqAnchor != actual.seqAnchor:
|
elif expected.seqAnchor != actual.seqAnchor:
|
||||||
echo "[seq.anchor] expected ", expected.seqAnchor, ", got ",
|
echo "[seq.anchor] expected ", expected.seqAnchor, ", got ",
|
||||||
actual.seqAnchor
|
actual.seqAnchor
|
||||||
else:
|
else: echo "[seq] Unknown difference"
|
||||||
echo "[seq] Unknown difference"
|
|
||||||
of yamlAlias:
|
of yamlAlias:
|
||||||
if expected.aliasTarget != actual.aliasTarget:
|
if expected.aliasTarget != actual.aliasTarget:
|
||||||
echo "[alias] expected ", expected.aliasTarget, ", got ",
|
echo "[alias] expected ", expected.aliasTarget, ", got ",
|
||||||
actual.aliasTarget
|
actual.aliasTarget
|
||||||
else:
|
else: echo "[alias] Unknown difference"
|
||||||
echo "[alias] Unknown difference"
|
else: echo "Unknown difference in event kind " & $expected.kind
|
||||||
else:
|
|
||||||
echo "Unknown difference in event kind " & $expected.kind
|
|
||||||
|
|
||||||
template ensure*(input: var YamlStream,
|
template ensure*(input: var YamlStream,
|
||||||
expected: varargs[YamlStreamEvent]) {.dirty.} =
|
expected: varargs[YamlStreamEvent]) {.dirty.} =
|
||||||
|
|
232
test/parsing.nim
232
test/parsing.nim
|
@ -1,232 +0,0 @@
|
||||||
# NimYAML - YAML implementation in Nim
|
|
||||||
# (c) Copyright 2015 Felix Krause
|
|
||||||
#
|
|
||||||
# See the file "copying.txt", included in this
|
|
||||||
# distribution, for details about the copyright.
|
|
||||||
|
|
||||||
import "../yaml"
|
|
||||||
|
|
||||||
import unittest, common
|
|
||||||
|
|
||||||
template ensure(input: string, expected: varargs[YamlStreamEvent]) {.dirty.} =
|
|
||||||
var
|
|
||||||
parser = newYamlParser(tagLib)
|
|
||||||
events = parser.parse(newStringStream(input))
|
|
||||||
try: ensure(events, expected)
|
|
||||||
except YamlParserError:
|
|
||||||
let e = cast[ref YamlParserError](getCurrentException())
|
|
||||||
echo "Parser error:", getCurrentExceptionMsg()
|
|
||||||
echo e.lineContent
|
|
||||||
fail()
|
|
||||||
|
|
||||||
suite "Parsing":
|
|
||||||
setup:
|
|
||||||
var tagLib = initCoreTagLibrary()
|
|
||||||
teardown:
|
|
||||||
discard
|
|
||||||
|
|
||||||
test "Parsing: Simple scalarEvent":
|
|
||||||
ensure("scalarEvent", startDocEvent(), scalarEvent("scalarEvent"), endDocEvent())
|
|
||||||
test "Parsing: Simple Sequence":
|
|
||||||
ensure("- off", startDocEvent(), startSeqEvent(),
|
|
||||||
scalarEvent("off"), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Simple Map":
|
|
||||||
ensure("42: value\nkey2: -7.5", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("42"), scalarEvent("value"), scalarEvent("key2"),
|
|
||||||
scalarEvent("-7.5"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Explicit Map":
|
|
||||||
ensure("? null\n: value\n? ON\n: value2", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("null"), scalarEvent("value"),
|
|
||||||
scalarEvent("ON"), scalarEvent("value2"),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Mixed Map (explicit to implicit)":
|
|
||||||
ensure("? a\n: 13\n1.5: d", startDocEvent(), startMapEvent(), scalarEvent("a"),
|
|
||||||
scalarEvent("13"), scalarEvent("1.5"),
|
|
||||||
scalarEvent("d"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Mixed Map (implicit to explicit)":
|
|
||||||
ensure("a: 4.2\n? 23\n: d", startDocEvent(), startMapEvent(), scalarEvent("a"),
|
|
||||||
scalarEvent("4.2"), scalarEvent("23"),
|
|
||||||
scalarEvent("d"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Missing values in map":
|
|
||||||
ensure("? a\n? b\nc:", startDocEvent(), startMapEvent(), scalarEvent("a"), scalarEvent(""),
|
|
||||||
scalarEvent("b"), scalarEvent(""), scalarEvent("c"), scalarEvent(""), endMapEvent(),
|
|
||||||
endDocEvent())
|
|
||||||
test "Parsing: Missing keys in map":
|
|
||||||
ensure(": a\n: b", startDocEvent(), startMapEvent(), scalarEvent(""), scalarEvent("a"),
|
|
||||||
scalarEvent(""), scalarEvent("b"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Multiline scalarEvents in explicit map":
|
|
||||||
ensure("? a\n true\n: null\n d\n? e\n 42", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("a true"), scalarEvent("null d"), scalarEvent("e 42"), scalarEvent(""),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Map in Sequence":
|
|
||||||
ensure(" - key: value\n key2: value2\n -\n key3: value3",
|
|
||||||
startDocEvent(), startSeqEvent(), startMapEvent(), scalarEvent("key"),
|
|
||||||
scalarEvent("value"), scalarEvent("key2"), scalarEvent("value2"), endMapEvent(),
|
|
||||||
startMapEvent(), scalarEvent("key3"), scalarEvent("value3"), endMapEvent(),
|
|
||||||
endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Sequence in Map":
|
|
||||||
ensure("key:\n - item1\n - item2", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("key"), startSeqEvent(), scalarEvent("item1"), scalarEvent("item2"),
|
|
||||||
endSeqEvent(), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Sequence in Sequence":
|
|
||||||
ensure("- - l1_i1\n - l1_i2\n- l2_i1", startDocEvent(), startSeqEvent(),
|
|
||||||
startSeqEvent(), scalarEvent("l1_i1"), scalarEvent("l1_i2"), endSeqEvent(),
|
|
||||||
scalarEvent("l2_i1"), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Flow Sequence":
|
|
||||||
ensure("[2, b]", startDocEvent(), startSeqEvent(), scalarEvent("2"),
|
|
||||||
scalarEvent("b"), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Flow Map":
|
|
||||||
ensure("{a: Y, 1.337: d}", startDocEvent(), startMapEvent(), scalarEvent("a"),
|
|
||||||
scalarEvent("Y"), scalarEvent("1.337"),
|
|
||||||
scalarEvent("d"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Flow Sequence in Flow Sequence":
|
|
||||||
ensure("[a, [b, c]]", startDocEvent(), startSeqEvent(), scalarEvent("a"),
|
|
||||||
startSeqEvent(), scalarEvent("b"), scalarEvent("c"), endSeqEvent(),
|
|
||||||
endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Flow Sequence in Flow Map":
|
|
||||||
ensure("{a: [b, c], [d, e]: f}", startDocEvent(), startMapEvent(), scalarEvent("a"),
|
|
||||||
startSeqEvent(), scalarEvent("b"), scalarEvent("c"), endSeqEvent(),
|
|
||||||
startSeqEvent(), scalarEvent("d"), scalarEvent("e"), endSeqEvent(),
|
|
||||||
scalarEvent("f"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Flow Sequence in Map":
|
|
||||||
ensure("a: [b, c]", startDocEvent(), startMapEvent(), scalarEvent("a"),
|
|
||||||
startSeqEvent(), scalarEvent("b"), scalarEvent("c"), endSeqEvent(),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Flow Map in Sequence":
|
|
||||||
ensure("- {a: b}", startDocEvent(), startSeqEvent(), startMapEvent(), scalarEvent("a"),
|
|
||||||
scalarEvent("b"), endMapEvent(), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Multiline scalar (top level)":
|
|
||||||
ensure("a\nb \n c\nd", startDocEvent(), scalarEvent("a b c d"), endDocEvent())
|
|
||||||
test "Parsing: Multiline scalar (in map)":
|
|
||||||
ensure("a: b\n c\nd:\n e\n f", startDocEvent(), startMapEvent(), scalarEvent("a"),
|
|
||||||
scalarEvent("b c"), scalarEvent("d"), scalarEvent("e f"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Block scalar (literal)":
|
|
||||||
ensure("a: |\x0A ab\x0A \x0A cd\x0A ef\x0A \x0A", startDocEvent(),
|
|
||||||
startMapEvent(), scalarEvent("a"), scalarEvent("ab\x0A\x0Acd\x0Aef\x0A", yTagExclamationmark),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Block scalar (folded)":
|
|
||||||
ensure("a: >\x0A ab\x0A cd\x0A \x0A ef\x0A\x0A\x0A gh\x0A", startDocEvent(),
|
|
||||||
startMapEvent(), scalarEvent("a"), scalarEvent("ab cd\x0Aef\x0A\x0Agh\x0A", yTagExclamationmark),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Block scalar (keep)":
|
|
||||||
ensure("a: |+\x0A ab\x0A \x0A \x0A", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("a"), scalarEvent("ab\x0A\x0A \x0A", yTagExclamationmark), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Block scalar (strip)":
|
|
||||||
ensure("a: |-\x0A ab\x0A \x0A \x0A", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("a"), scalarEvent("ab", yTagExclamationmark), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: non-specific tags of quoted strings":
|
|
||||||
ensure("\"a\"", startDocEvent(),
|
|
||||||
scalarEvent("a", yTagExclamationMark), endDocEvent())
|
|
||||||
test "Parsing: explicit non-specific tag":
|
|
||||||
ensure("! a", startDocEvent(), scalarEvent("a", yTagExclamationMark), endDocEvent())
|
|
||||||
test "Parsing: secondary tag handle resolution":
|
|
||||||
ensure("!!str a", startDocEvent(), scalarEvent("a", yTagString), endDocEvent())
|
|
||||||
test "Parsing: resolving custom tag handles":
|
|
||||||
let fooId = tagLib.registerUri("tag:example.com,2015:foo")
|
|
||||||
ensure("%TAG !t! tag:example.com,2015:\n---\n!t!foo a", startDocEvent(),
|
|
||||||
scalarEvent("a", fooId), endDocEvent())
|
|
||||||
test "Parsing: tags in sequence":
|
|
||||||
ensure(" - !!str a\n - b\n - !!int c\n - d", startDocEvent(),
|
|
||||||
startSeqEvent(), scalarEvent("a", yTagString), scalarEvent("b"),
|
|
||||||
scalarEvent("c", yTagInteger), scalarEvent("d"), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: tags in implicit map":
|
|
||||||
ensure("!!str a: b\nc: !!int d\ne: !!str f\ng: h", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("a", yTagString), scalarEvent("b"), scalarEvent("c"),
|
|
||||||
scalarEvent("d", yTagInteger), scalarEvent("e"), scalarEvent("f", yTagString),
|
|
||||||
scalarEvent("g"), scalarEvent("h"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: tags in explicit map":
|
|
||||||
ensure("? !!str a\n: !!int b\n? c\n: !!str d", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("a", yTagString), scalarEvent("b", yTagInteger), scalarEvent("c"),
|
|
||||||
scalarEvent("d", yTagString), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: tags for block objects":
|
|
||||||
ensure("--- !!map\nfoo: !!seq\n - a\n - !!str b\n!!str bar: !!str baz",
|
|
||||||
startDocEvent(), startMapEvent(yTagMap), scalarEvent("foo"),
|
|
||||||
startSeqEvent(yTagSequence), scalarEvent("a"), scalarEvent("b", yTagString),
|
|
||||||
endSeqEvent(), scalarEvent("bar", yTagString),
|
|
||||||
scalarEvent("baz", yTagString), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: root tag for block sequence":
|
|
||||||
ensure("--- !!seq\n- a", startDocEvent(), startSeqEvent(yTagSequence),
|
|
||||||
scalarEvent("a"), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: root tag for explicit block map":
|
|
||||||
ensure("--- !!map\n? a\n: b", startDocEvent(), startMapEvent(yTagMap),
|
|
||||||
scalarEvent("a"), scalarEvent("b"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: tags for flow objects":
|
|
||||||
ensure("!!map { k: !!seq [ a, !!str b] }", startDocEvent(), startMapEvent(yTagMap),
|
|
||||||
scalarEvent("k"), startSeqEvent(yTagSequence), scalarEvent("a"),
|
|
||||||
scalarEvent("b", yTagString), endSeqEvent(), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Tag after directives end":
|
|
||||||
ensure("--- !!str\nfoo", startDocEvent(), scalarEvent("foo", yTagString), endDocEvent())
|
|
||||||
test "Parsing: Simple Anchor":
|
|
||||||
ensure("&a str", startDocEvent(), scalarEvent("str", yTagQuestionMark,
|
|
||||||
0.AnchorId), endDocEvent())
|
|
||||||
test "Parsing: Anchors in sequence":
|
|
||||||
ensure(" - &a a\n - b\n - &c c\n - &a d", startDocEvent(), startSeqEvent(),
|
|
||||||
scalarEvent("a", yTagQuestionMark, 0.AnchorId), scalarEvent("b"),
|
|
||||||
scalarEvent("c", yTagQuestionMark, 1.AnchorId),
|
|
||||||
scalarEvent("d", yTagQuestionMark, 2.AnchorId), endSeqEvent(),
|
|
||||||
endDocEvent())
|
|
||||||
test "Parsing: Anchors in map":
|
|
||||||
ensure("&a a: b\nc: &d d", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("a", yTagQuestionMark, 0.AnchorId),
|
|
||||||
scalarEvent("b"), scalarEvent("c"),
|
|
||||||
scalarEvent("d", yTagQuestionMark, 1.AnchorId),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Anchors and tags":
|
|
||||||
ensure(" - &a !!str a\n - !!int b\n - &c !!int c\n - &d d", startDocEvent(),
|
|
||||||
startSeqEvent(), scalarEvent("a", yTagString, 0.AnchorId),
|
|
||||||
scalarEvent("b", yTagInteger), scalarEvent("c", yTagInteger, 1.AnchorId),
|
|
||||||
scalarEvent("d", yTagQuestionMark, 2.AnchorId), endSeqEvent(),
|
|
||||||
endDocEvent())
|
|
||||||
test "Parsing: Aliases in sequence":
|
|
||||||
ensure(" - &a a\n - &b b\n - *a\n - *b", startDocEvent(), startSeqEvent(),
|
|
||||||
scalarEvent("a", yTagQuestionMark, 0.AnchorId),
|
|
||||||
scalarEvent("b", yTagQuestionMark, 1.AnchorId), aliasEvent(0.AnchorId),
|
|
||||||
aliasEvent(1.AnchorId), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Aliases in map":
|
|
||||||
ensure("&a a: &b b\n*a : *b", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("a", yTagQuestionMark, 0.AnchorId),
|
|
||||||
scalarEvent("b", yTagQuestionMark, 1.AnchorId), aliasEvent(0.AnchorId),
|
|
||||||
aliasEvent(1.AnchorId), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Aliases in flow":
|
|
||||||
ensure("{ &a [a, &b b]: *b, *a : [c, *b, d]}", startDocEvent(), startMapEvent(),
|
|
||||||
startSeqEvent(yTagQuestionMark, 0.AnchorId), scalarEvent("a"),
|
|
||||||
scalarEvent("b", yTagQuestionMark, 1.AnchorId), endSeqEvent(),
|
|
||||||
aliasEvent(1.AnchorId), aliasEvent(0.AnchorId), startSeqEvent(),
|
|
||||||
scalarEvent("c"), aliasEvent(1.AnchorId), scalarEvent("d"), endSeqEvent(),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Tags on empty scalars":
|
|
||||||
ensure("!!str : a\nb: !!int\n!!str : !!str", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("", yTagString), scalarEvent("a"), scalarEvent("b"),
|
|
||||||
scalarEvent("", yTagInteger), scalarEvent("", yTagString),
|
|
||||||
scalarEvent("", yTagString), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Anchors on empty scalars":
|
|
||||||
ensure("&a : a\nb: &b\n&c : &a", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("", yTagQuestionMark, 0.AnchorId), scalarEvent("a"),
|
|
||||||
scalarEvent("b"), scalarEvent("", yTagQuestionMark, 1.AnchorId),
|
|
||||||
scalarEvent("", yTagQuestionMark, 2.AnchorId),
|
|
||||||
scalarEvent("", yTagQuestionMark, 3.AnchorId), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Whitespace before end of flow content":
|
|
||||||
ensure("- [a, b, c ]", startDocEvent(), startSeqEvent(),
|
|
||||||
startSeqEvent(), scalarEvent("a"), scalarEvent("b"),
|
|
||||||
scalarEvent("c"), endSeqEvent(), endSeqEvent(), endDocEvent())
|
|
||||||
test "Parsing: Empty lines after document":
|
|
||||||
ensure(":\n\n", startDocEvent(), startMapEvent(), scalarEvent(""),
|
|
||||||
scalarEvent(""), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Empty lines between map elements":
|
|
||||||
ensure("1: 2\n\n\n3: 4", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("1"), scalarEvent("2"), scalarEvent("3"),
|
|
||||||
scalarEvent("4"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Sequence beginning at same line as map key":
|
|
||||||
ensure("1:\n- 2\n- 3\n4: 5", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("1"), startSeqEvent(), scalarEvent("2"),
|
|
||||||
scalarEvent("3"), endSeqEvent(), scalarEvent("4"),
|
|
||||||
scalarEvent("5"), endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Sequence beginning at same line as map key with > 0 indent":
|
|
||||||
ensure(" foo:\n - bar\n baz:", startDocEvent(), startMapEvent(),
|
|
||||||
scalarEvent("foo"), startSeqEvent(), scalarEvent("bar"),
|
|
||||||
endSeqEvent(), scalarEvent("baz"), scalarEvent(""),
|
|
||||||
endMapEvent(), endDocEvent())
|
|
||||||
test "Parsing: Colon in double quoted string":
|
|
||||||
ensure("\"foo: bar\\\": baz\"", startDocEvent(),
|
|
||||||
scalarEvent("foo: bar\": baz", yTagExclamationMark),
|
|
||||||
endDocEvent())
|
|
|
@ -4,4 +4,4 @@
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
||||||
import parsing, constructingJson, serializing, dom
|
import constructingJson, serializing, dom
|
36
yaml.nim
36
yaml.nim
|
@ -20,8 +20,7 @@ import streams, unicode, lexbase, tables, strutils, json, hashes, queues,
|
||||||
macros, typetraits, parseutils
|
macros, typetraits, parseutils
|
||||||
export streams, tables, json
|
export streams, tables, json
|
||||||
|
|
||||||
when defined(yamlDebug):
|
when defined(yamlDebug): import terminal
|
||||||
import terminal
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TypeHint* = enum
|
TypeHint* = enum
|
||||||
|
@ -50,9 +49,9 @@ type
|
||||||
|
|
||||||
YamlStreamEventKind* = enum
|
YamlStreamEventKind* = enum
|
||||||
## Kinds of YAML events that may occur in an ``YamlStream``. Event kinds
|
## Kinds of YAML events that may occur in an ``YamlStream``. Event kinds
|
||||||
## are discussed in ``YamlStreamEvent``.
|
## are discussed in `YamlStreamEvent <#YamlStreamEvent>`_.
|
||||||
yamlStartDocument, yamlEndDocument, yamlStartMap, yamlEndMap,
|
yamlStartDoc, yamlEndDoc, yamlStartMap, yamlEndMap,
|
||||||
yamlStartSequence, yamlEndSequence, yamlScalar, yamlAlias
|
yamlStartSeq, yamlEndSeq, yamlScalar, yamlAlias
|
||||||
|
|
||||||
TagId* = distinct int ## \
|
TagId* = distinct int ## \
|
||||||
## A ``TagId`` identifies a tag URI, like for example
|
## A ``TagId`` identifies a tag URI, like for example
|
||||||
|
@ -76,7 +75,7 @@ type
|
||||||
|
|
||||||
YamlStreamEvent* = object
|
YamlStreamEvent* = object
|
||||||
## An element from a `YamlStream <#YamlStream>`_. Events that start an
|
## An element from a `YamlStream <#YamlStream>`_. Events that start an
|
||||||
## object (``yamlStartMap``, ``yamlStartSequence``, ``yamlScalar``) have
|
## object (``yamlStartMap``, ``yamlStartSeq``, ``yamlScalar``) have
|
||||||
## an optional anchor and a tag associated with them. The anchor will be
|
## an optional anchor and a tag associated with them. The anchor will be
|
||||||
## set to ``yAnchorNone`` if it doesn't exist.
|
## set to ``yAnchorNone`` if it doesn't exist.
|
||||||
##
|
##
|
||||||
|
@ -89,32 +88,31 @@ type
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
mapAnchor* : AnchorId
|
mapAnchor* : AnchorId
|
||||||
mapTag* : TagId
|
mapTag* : TagId
|
||||||
of yamlStartSequence:
|
of yamlStartSeq:
|
||||||
seqAnchor* : AnchorId
|
seqAnchor* : AnchorId
|
||||||
seqTag* : TagId
|
seqTag* : TagId
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
scalarAnchor* : AnchorId
|
scalarAnchor* : AnchorId
|
||||||
scalarTag* : TagId
|
scalarTag* : TagId
|
||||||
scalarContent*: string # may not be nil (but empty)
|
scalarContent*: string # may not be nil (but empty)
|
||||||
of yamlEndMap, yamlEndSequence, yamlStartDocument, yamlEndDocument:
|
of yamlEndMap, yamlEndSeq, yamlStartDoc, yamlEndDoc:
|
||||||
discard
|
discard
|
||||||
of yamlAlias:
|
of yamlAlias:
|
||||||
aliasTarget* : AnchorId
|
aliasTarget* : AnchorId
|
||||||
|
|
||||||
YamlStream* = object ## \
|
YamlStream* = object ## \
|
||||||
## A ``YamlStream`` is an iterator-like object that yields a
|
## A ``YamlStream`` is an iterator-like object that yields a
|
||||||
## well-formed stream of
|
## well-formed stream of ``YamlStreamEvents``. Well-formed means that
|
||||||
## ``YamlStreamEvents``. Well-formed means that every ``yamlStartMap``
|
## every ``yamlStartMap`` is terminated by a ``yamlEndMap``, every
|
||||||
## is terminated by a ``yamlEndMap``, every ``yamlStartSequence`` is
|
## ``yamlStartSeq`` is terminated by a ``yamlEndSeq`` and every
|
||||||
## terminated by a ``yamlEndSequence`` and every ``yamlStartDocument``
|
## ``yamlStartDoc`` is terminated by a ``yamlEndDoc``. Moreover, every
|
||||||
## is terminated by a ``yamlEndDocument``. Moreover, every emitted map
|
## emitted mapping has an even number of children.
|
||||||
## has an even number of children.
|
|
||||||
##
|
##
|
||||||
## The creator of a ``YamlStream`` is responsible for it being
|
## The creator of a ``YamlStream`` is responsible for it being
|
||||||
## well-formed. A user of the stream may assume that it is well-formed
|
## well-formed. A user of the stream may assume that it is well-formed
|
||||||
## and is not required to check for it. The procs in this module will
|
## and is not required to check for it. The procs in this module will
|
||||||
## always yield a well-formed ``YamlStream`` and expect it to be
|
## always yield a well-formed ``YamlStream`` and expect it to be
|
||||||
## well-formed if it's an input.
|
## well-formed if they take it as input parameter.
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
backend: iterator(): YamlStreamEvent
|
backend: iterator(): YamlStreamEvent
|
||||||
|
@ -168,9 +166,9 @@ type
|
||||||
## for the non-specific tags ``?`` and ``!``, uses flow style, quotes
|
## for the non-specific tags ``?`` and ``!``, uses flow style, quotes
|
||||||
## all string scalars.
|
## all string scalars.
|
||||||
## - ``ypsDefault``: Tries to be as human-readable as possible. Uses
|
## - ``ypsDefault``: Tries to be as human-readable as possible. Uses
|
||||||
## block style by default, but tries to condense maps and sequences
|
## block style by default, but tries to condense mappings and
|
||||||
## which only contain scalar nodes into a single line using flow
|
## sequences which only contain scalar nodes into a single line using
|
||||||
## style.
|
## flow style.
|
||||||
## - ``ypsJson``: Omits the ``%YAML`` directive and the ``---``
|
## - ``ypsJson``: Omits the ``%YAML`` directive and the ``---``
|
||||||
## marker. Uses flow style. Flattens anchors and aliases, omits tags.
|
## marker. Uses flow style. Flattens anchors and aliases, omits tags.
|
||||||
## Output will be parseable as JSON. ``YamlStream`` to dump may only
|
## Output will be parseable as JSON. ``YamlStream`` to dump may only
|
||||||
|
@ -333,7 +331,7 @@ const
|
||||||
## `!!str <http://yaml.org/type/str.html >`_ tag
|
## `!!str <http://yaml.org/type/str.html >`_ tag
|
||||||
yTagSequence* : TagId = 3.TagId ## \
|
yTagSequence* : TagId = 3.TagId ## \
|
||||||
## `!!seq <http://yaml.org/type/seq.html>`_ tag
|
## `!!seq <http://yaml.org/type/seq.html>`_ tag
|
||||||
yTagMap* : TagId = 4.TagId ## \
|
yTagMapping* : TagId = 4.TagId ## \
|
||||||
## `!!map <http://yaml.org/type/map.html>`_ tag
|
## `!!map <http://yaml.org/type/map.html>`_ tag
|
||||||
|
|
||||||
# json & core schema
|
# json & core schema
|
||||||
|
|
Loading…
Reference in New Issue