fixes #101, minor improvements

* improved error reporting on wrong tags
 * removed a debug `echo` call
 * fixed problems with sparse objects and Option (#101)
This commit is contained in:
Felix Krause 2023-11-05 15:10:29 +01:00
parent 624cbe59b3
commit 854d33378e
4 changed files with 30 additions and 11 deletions

View File

@ -265,6 +265,19 @@ suite "Serialization":
let output = blockOnlyDumper().dump(input)
assertStringEqual "- !!null ~\n- 42\n- !!null ~\n", output
dualTest "Load Option of seq":
let input = "- !!null\n- [a, b]"
var result: array[0..1, Option[seq[string]]]
load(input, result)
assert not result[0].isSome
assert result[1].get()[0] == "a"
assert result[1].get()[1] == "b"
test "Dump Option of seq":
let input = [none(seq[string]), some(@["a", "b"])]
let output = Dumper().dump(input)
assertStringEqual "- !!null ~\n- [a, b]\n", output
dualTest "Load Table[int, string]":
let input = "23: dreiundzwanzig\n42: zweiundvierzig"
var result: Table[int32, string]

View File

@ -38,6 +38,7 @@ proc load*[K](input: Stream | string, target: var K)
if e.parent of IOError: raise (ref IOError)(e.parent)
if e.parent of OSError: raise (ref OSError)(e.parent)
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
elif e.parent of YamlConstructionError: raise (ref YamlConstructionError)(e.parent)
else: internalError("Unexpected exception: " & $e.parent.name)
proc loadAs*[K](input: Stream | string): K {.raises:

View File

@ -827,8 +827,8 @@ proc hasSparse(t: typedesc): bool {.compileTime.} =
proc getOptionInner(fType: NimNode): NimNode {.compileTime.} =
if fType.kind == nnkBracketExpr and len(fType) == 2 and
fType[1].kind == nnkSym:
return newIdentNode($fType[1])
fType[0].kind == nnkSym:
return fType[1]
else: return nil
proc checkMissing(
@ -850,7 +850,7 @@ proc checkMissing(
when `o`.`field`.hasCustomPragma(defaultVal):
`o`.`field` = `o`.`field`.getCustomPragmaVal(defaultVal)
elif hasSparse(`t`) and `o`.`field` is Option:
`o`.`field` = none(`optionInner`)
`o`.`field` = none[`optionInner`]()
else:
raise constructionError(`s`, `m`, "While constructing " & `tName` &
": Missing field: " & `fName`)
@ -1447,17 +1447,20 @@ proc constructChild*[T](
of yamlScalar:
if item.scalarProperties.tag notin [yTagQuestionMark, yTagExclamationMark,
yamlTag(T)]:
raise ctx.input.constructionError(item.startPos, "Wrong tag for " & typetraits.name(T))
raise ctx.input.constructionError(
item.startPos, "Wrong tag for " & typetraits.name(T) & ": " & $item.scalarProperties.tag)
elif item.scalarProperties.anchor != yAnchorNone:
raise ctx.input.constructionError(item.startPos, "Anchor on non-ref type")
of yamlStartMap:
if item.mapProperties.tag notin [yTagQuestionMark, yamlTag(T)]:
raise ctx.input.constructionError(item.startPos, "Wrong tag for " & typetraits.name(T))
raise ctx.input.constructionError(
item.startPos, "Wrong tag for " & typetraits.name(T) & ": " & $item.mapProperties.tag)
elif item.mapProperties.anchor != yAnchorNone:
raise ctx.input.constructionError(item.startPos, "Anchor on non-ref type")
of yamlStartSeq:
if item.seqProperties.tag notin [yTagQuestionMark, yamlTag(T)]:
raise ctx.input.constructionError(item.startPos, "Wrong tag for " & typetraits.name(T))
raise ctx.input.constructionError(
item.startPos, "Wrong tag for " & typetraits.name(T) & ": " & $item.seqProperties.tag)
elif item.seqProperties.anchor != yAnchorNone:
raise ctx.input.constructionError(item.startPos, "Anchor on non-ref type")
of yamlAlias:
@ -1474,7 +1477,8 @@ proc constructChild*(
if item.kind == yamlScalar:
if item.scalarProperties.tag notin
[yTagQuestionMark, yTagExclamationMark, yamlTag(string)]:
raise ctx.input.constructionError(item.startPos, "Wrong tag for string")
raise ctx.input.constructionError(
item.startPos, "Wrong tag for string: " & $item.scalarProperties.tag)
elif item.scalarProperties.anchor != yAnchorNone:
raise ctx.input.constructionError(item.startPos, "Anchor on non-ref type")
ctx.constructObject(result)
@ -1486,7 +1490,8 @@ proc constructChild*[T](
let item = ctx.input.peek()
if item.kind == yamlStartSeq:
if item.seqProperties.tag notin [yTagQuestionMark, yamlTag(seq[T])]:
raise ctx.input.constructionError(item.startPos, "Wrong tag for " & typetraits.name(seq[T]))
raise ctx.input.constructionError(
item.startPos, "Wrong tag for " & typetraits.name(seq[T]) & ": " & $item.seqProperties.tag)
elif item.seqProperties.anchor != yAnchorNone:
raise ctx.input.constructionError(item.startPos, "Anchor on non-ref type")
ctx.constructObject(result)
@ -1498,7 +1503,8 @@ proc constructChild*[I, T](
let item = ctx.input.peek()
if item.kind == yamlStartSeq:
if item.seqProperties.tag notin [yTagQuestionMark, yamlTag(array[I, T])]:
raise ctx.input.constructionError(item.startPos, "Wrong tag for " & typetraits.name(array[I, T]))
raise ctx.input.constructionError(
item.startPos, "Wrong tag for " & typetraits.name(array[I, T]) & ": " & $item.seqProperties.tag)
elif item.seqProperties.anchor != yAnchorNone:
raise ctx.input.constructionError(item.startPos, "Anchor on non-ref type")
ctx.constructObject(result)
@ -1528,7 +1534,7 @@ when defined(JS):
let e = ctx.input.peek()
if e.kind == yamlScalar:
if e.scalarProperties.tag notin [yTagQuestionMark, yTagTimestamp]:
raise ctx.input.constructionError(e.startPos, "Wrong tag for Time")
raise ctx.input.constructionError(e.startPos, "Wrong tag for Time: " & $e.scalarProperties.tag)
elif guessType(e.scalarContent) != yTypeTimestamp:
raise ctx.input.constructionError(e.startPos, "Invalid timestamp")
elif e.scalarProperties.anchor != yAnchorNone:

View File

@ -547,7 +547,6 @@ proc doPresent(
ctx.target.write("%YAML 1.1")
ctx.newline()
wroteDirectivesEnd = true
echo "write --- because %YAML"
of ovNone: discard
for v in ctx.handles:
if v.handle == "!":