mirror of https://github.com/status-im/NimYAML.git
Support missing keys/values in maps
This commit is contained in:
parent
ca077e54ca
commit
545bff673a
|
@ -192,7 +192,8 @@ template yieldDocumentEnd() {.dirty.} =
|
||||||
template closeLevel(lvl: DocumentLevel) {.dirty.} =
|
template closeLevel(lvl: DocumentLevel) {.dirty.} =
|
||||||
case lvl.mode
|
case lvl.mode
|
||||||
of mExplicitBlockMapKey, mFlowMapKey:
|
of mExplicitBlockMapKey, mFlowMapKey:
|
||||||
yieldError("Missing Map value!")
|
yieldScalar("")
|
||||||
|
yield YamlParserEvent(kind: yamlEndMap)
|
||||||
of mImplicitBlockMapKey, mBlockMapValue, mFlowMapValue:
|
of mImplicitBlockMapKey, mBlockMapValue, mFlowMapValue:
|
||||||
yield YamlParserEvent(kind: yamlEndMap)
|
yield YamlParserEvent(kind: yamlEndMap)
|
||||||
of mBlockSequenceItem, mFlowSequenceItem:
|
of mBlockSequenceItem, mFlowSequenceItem:
|
||||||
|
@ -225,9 +226,10 @@ template closeAllLevels() {.dirty.} =
|
||||||
if ancestry.len == 0: break
|
if ancestry.len == 0: break
|
||||||
level = ancestry.pop()
|
level = ancestry.pop()
|
||||||
|
|
||||||
template handleBlockIndicator(expected: openarray[DocumentLevelMode],
|
template handleBlockIndicator(expected, possible: openarray[DocumentLevelMode],
|
||||||
next: DocumentLevelMode,
|
next: DocumentLevelMode,
|
||||||
entering: YamlParserEventKind) {.dirty.} =
|
entering: YamlParserEventKind,
|
||||||
|
emptyScalarOnOpening: bool = false) {.dirty.} =
|
||||||
leaveMoreIndentedLevels()
|
leaveMoreIndentedLevels()
|
||||||
if level.indicatorColumn == lex.column or
|
if level.indicatorColumn == lex.column or
|
||||||
level.indicatorColumn == -1 and level.indentationColumn == lex.column:
|
level.indicatorColumn == -1 and level.indentationColumn == lex.column:
|
||||||
|
@ -236,6 +238,17 @@ template handleBlockIndicator(expected: openarray[DocumentLevelMode],
|
||||||
ancestry.add(level)
|
ancestry.add(level)
|
||||||
level = DocumentLevel(mode: mUnknown, indicatorColumn: -1,
|
level = DocumentLevel(mode: mUnknown, indicatorColumn: -1,
|
||||||
indentationColumn: -1)
|
indentationColumn: -1)
|
||||||
|
else:
|
||||||
|
# `in` does not work if possible is [], so we have to check for that
|
||||||
|
when possible.len > 0:
|
||||||
|
if level.mode in possible:
|
||||||
|
yieldScalar("")
|
||||||
|
level.mode = next
|
||||||
|
ancestry.add(level)
|
||||||
|
level = DocumentLevel(mode: mUnknown, indicatorColumn: -1,
|
||||||
|
indentationColumn: -1)
|
||||||
|
else:
|
||||||
|
yieldError("Invalid token after " & $level.mode)
|
||||||
else:
|
else:
|
||||||
yieldError("Invalid token after " & $level.mode)
|
yieldError("Invalid token after " & $level.mode)
|
||||||
elif level.mode != mUnknown:
|
elif level.mode != mUnknown:
|
||||||
|
@ -246,6 +259,8 @@ template handleBlockIndicator(expected: openarray[DocumentLevelMode],
|
||||||
level.mode = next
|
level.mode = next
|
||||||
level.indicatorColumn = lex.column
|
level.indicatorColumn = lex.column
|
||||||
yieldStart(entering)
|
yieldStart(entering)
|
||||||
|
if emptyScalarOnOpening:
|
||||||
|
yieldScalar("")
|
||||||
ancestry.add(level)
|
ancestry.add(level)
|
||||||
level = DocumentLevel(mode: mUnknown, indicatorColumn: -1,
|
level = DocumentLevel(mode: mUnknown, indicatorColumn: -1,
|
||||||
indentationColumn: -1)
|
indentationColumn: -1)
|
||||||
|
@ -381,14 +396,16 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
of yamlLineStart:
|
of yamlLineStart:
|
||||||
discard
|
discard
|
||||||
of yamlDash:
|
of yamlDash:
|
||||||
handleBlockIndicator([mBlockSequenceItem], mBlockSequenceItem,
|
handleBlockIndicator([mBlockSequenceItem], [],
|
||||||
yamlStartSequence)
|
mBlockSequenceItem, yamlStartSequence)
|
||||||
of yamlQuestionmark:
|
of yamlQuestionmark:
|
||||||
handleBlockIndicator([mImplicitBlockMapKey, mBlockMapValue],
|
handleBlockIndicator([mImplicitBlockMapKey, mBlockMapValue],
|
||||||
|
[mExplicitBlockMapKey],
|
||||||
mExplicitBlockMapKey, yamlStartMap)
|
mExplicitBlockMapKey, yamlStartMap)
|
||||||
of yamlColon:
|
of yamlColon:
|
||||||
handleBlockIndicator([mExplicitBlockMapKey],
|
handleBlockIndicator([mExplicitBlockMapKey],
|
||||||
mBlockMapValue, yamlError)
|
[mBlockMapValue, mImplicitBlockMapKey],
|
||||||
|
mBlockMapValue, yamlStartMap, true)
|
||||||
of yamlPipe, yamlGreater:
|
of yamlPipe, yamlGreater:
|
||||||
blockScalar = if token == yamlPipe: bsLiteral else: bsFolded
|
blockScalar = if token == yamlPipe: bsLiteral else: bsFolded
|
||||||
blockScalarIndentation = -1
|
blockScalarIndentation = -1
|
||||||
|
@ -419,15 +436,16 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
scalarCacheIsQuoted = false
|
scalarCacheIsQuoted = false
|
||||||
scalarIndentation = lex.column
|
scalarIndentation = lex.column
|
||||||
of mBlockMapValue:
|
of mBlockMapValue:
|
||||||
ancestry.add(level)
|
|
||||||
scalarCache = lex.content
|
scalarCache = lex.content
|
||||||
scalarCacheIsQuoted = false
|
scalarCacheIsQuoted = false
|
||||||
scalarIndentation = lex.column
|
scalarIndentation = lex.column
|
||||||
level = DocumentLevel(mode: mScalar, indicatorColumn: -1,
|
level.mode = mImplicitBlockMapKey
|
||||||
indentationColumn:
|
of mExplicitBlockMapKey:
|
||||||
ancestry[ancestry.high].indentationColumn + 1)
|
yieldScalar()
|
||||||
|
level.mode = mBlockMapValue
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
yieldError("Unexpected scalar")
|
yieldError("Unexpected scalar in " & $level.mode)
|
||||||
state = ylBlockAfterScalar
|
state = ylBlockAfterScalar
|
||||||
of lexer.yamlScalar:
|
of lexer.yamlScalar:
|
||||||
leaveMoreIndentedLevels()
|
leaveMoreIndentedLevels()
|
||||||
|
|
|
@ -68,15 +68,15 @@ proc printDifference(expected, actual: YamlParserEvent) =
|
||||||
let msg = "[scalar] expected content \"" &
|
let msg = "[scalar] expected content \"" &
|
||||||
expected.scalarContent & "\", got \"" &
|
expected.scalarContent & "\", got \"" &
|
||||||
actual.scalarContent & "\" "
|
actual.scalarContent & "\" "
|
||||||
|
if expected.scalarContent.len != actual.scalarContent.len:
|
||||||
|
echo msg, "(length does not match)"
|
||||||
|
else:
|
||||||
for i in 0..expected.scalarContent.high:
|
for i in 0..expected.scalarContent.high:
|
||||||
if i >= actual.scalarContent.high:
|
if expected.scalarContent[i] != actual.scalarContent[i]:
|
||||||
echo msg, "(expected more chars, first char missing: ",
|
|
||||||
cast[int](expected.scalarContent[i]), ")"
|
|
||||||
break
|
|
||||||
elif expected.scalarContent[i] != actual.scalarContent[i]:
|
|
||||||
echo msg, "(first different char at pos ", i,
|
echo msg, "(first different char at pos ", i,
|
||||||
": expected ",
|
": expected ",
|
||||||
cast[int](expected.scalarContent[i]), ", got ",
|
cast[int](expected.scalarContent[i]),
|
||||||
|
", got ",
|
||||||
cast[int](actual.scalarContent[i]), ")"
|
cast[int](actual.scalarContent[i]), ")"
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -135,6 +135,17 @@ suite "Parsing":
|
||||||
test "Parsing: Mixed Map (implicit to explicit)":
|
test "Parsing: Mixed Map (implicit to explicit)":
|
||||||
ensure("a: b\n? c\n: d", startDoc(), startMap(), scalar("a"),
|
ensure("a: b\n? c\n: d", startDoc(), startMap(), scalar("a"),
|
||||||
scalar("b"), scalar("c"), scalar("d"), endMap(), endDoc())
|
scalar("b"), scalar("c"), scalar("d"), endMap(), endDoc())
|
||||||
|
test "Parsing: Missing values in map":
|
||||||
|
ensure("? a\n? b\nc:", startDoc(), startMap(), scalar("a"), scalar(""),
|
||||||
|
scalar("b"), scalar(""), scalar("c"), scalar(""), endMap(),
|
||||||
|
endDoc())
|
||||||
|
test "Parsing: Missing keys in map":
|
||||||
|
ensure(": a\n: b", startDoc(), startMap(), scalar(""), scalar("a"),
|
||||||
|
scalar(""), scalar("b"), endMap(), endDoc())
|
||||||
|
test "Parsing: Multiline scalars in explicit map":
|
||||||
|
ensure("? a\n b\n: c\n d\n? e\n f", startDoc(), startMap(),
|
||||||
|
scalar("a b"), scalar("c d"), scalar("e f"), scalar(""),
|
||||||
|
endMap(), endDoc())
|
||||||
test "Parsing: Map in Sequence":
|
test "Parsing: Map in Sequence":
|
||||||
ensure(" - key: value", startDoc(), startSequence(), startMap(),
|
ensure(" - key: value", startDoc(), startSequence(), startMap(),
|
||||||
scalar("key"), scalar("value"), endMap(), endSequence(),
|
scalar("key"), scalar("value"), endMap(), endSequence(),
|
||||||
|
|
Loading…
Reference in New Issue