diff --git a/doc/index.txt b/doc/index.txt index 78a5d4e..064ce52 100644 --- a/doc/index.txt +++ b/doc/index.txt @@ -337,5 +337,85 @@ Loading Nim objects from JSON } ] +.. raw:: html + + +Processing a Sequence of Heterogeneous Items +-------------------------------------------- + +.. raw:: html + + +
code.nimin.yaml
+ +.. code-block:: nim + import yaml + type Person = object + name: string + + setTagUriForType(Person, "!nim:demo:Person", + yTagPerson) + + var + s = newFileStream("in.yaml", fmRead) + context = newConstructionContext() + parser = newYamlParser(serializationTagLibrary) + events = parser.parse(s) + + assert events.next().kind == yamlStartDoc + assert events.next().kind == yamlStartSeq + var nextEvent = events.peek() + while nextEvent.kind != yamlEndSeq: + var curTag = nextEvent.tag() + if curTag == yTagQuestionMark: + # we only support implicitly tagged scalar events + assert nextEvent.kind == yamlScalar + case guessType(nextEvent.scalarContent) + of yTypeInteger: curTag = yTagInteger + of yTypeBoolTrue, yTypeBoolFalse: + curTag = yTagBoolean + of yTypeUnknown: curTag = yTagString + else: assert false, "Type not supported!" + elif curTag == yTagExclamationMark: + curTag = yTagString + case curTag + of yTagString: + var s: string + events.constructChild(context, s) + echo "got string: ", s + of yTagInteger: + var i: int32 + events.constructChild(context, i) + echo "got integer: ", i + of yTagBoolean: + var b: bool + events.constructChild(context, b) + echo "got boolean: ", b + else: + # non-standard tag ids are not available + # at compile time + if curTag == yTagPerson: + var p: Person + events.constructChild(context, p) + echo "got Person with name: ", p.name + else: assert false, "unsupported tag: " & $curTag + nextEvent = events.peek() + assert events.next().kind == yamlEndSeq + assert events.next().kind == yamlEndDoc + assert events.finished() + s.close() + +.. raw:: html + + +.. code-block:: yaml + %YAML 1.2 + --- !!seq + - this is a string + - 42 + - false + - !!str 23 + - !nim:demo:Person {name: Trillian} + .. raw:: html
\ No newline at end of file diff --git a/private/events.nim b/private/events.nim index d270e91..7482a8e 100644 --- a/private/events.nim +++ b/private/events.nim @@ -42,6 +42,13 @@ proc `$`*(event: YamlStreamEvent): string = result &= "aliasTarget=" & $event.aliasTarget result &= ")" +proc tag*(event: YamlStreamEvent): TagId = + case event.kind + of yamlStartMap: result = event.mapTag + of yamlStartSeq: result = event.seqTag + of yamlScalar: result = event.scalarTag + else: raise newException(FieldError, "Event " & $event.kind & " has no tag") + proc startDocEvent*(): YamlStreamEvent = result = YamlStreamEvent(kind: yamlStartDoc) diff --git a/private/serialization.nim b/private/serialization.nim index 1a95549..7e93631 100644 --- a/private/serialization.nim +++ b/private/serialization.nim @@ -9,11 +9,11 @@ proc initRefNodeData(p: pointer): RefNodeData = result.count = 1 result.anchor = yAnchorNone -proc newConstructionContext(): ConstructionContext = +proc newConstructionContext*(): ConstructionContext = new(result) result.refs = initTable[AnchorId, pointer]() -proc newSerializationContext(s: AnchorStyle): SerializationContext = +proc newSerializationContext*(s: AnchorStyle): SerializationContext = new(result) result.refs = initTable[pointer, AnchorId]() result.style = s diff --git a/yaml.nim b/yaml.nim index 2e45fd6..b67491f 100644 --- a/yaml.nim +++ b/yaml.nim @@ -401,6 +401,8 @@ proc `==`*(left: YamlStreamEvent, right: YamlStreamEvent): bool {.raises: [].} proc `$`*(event: YamlStreamEvent): string {.raises: [].} ## outputs a human-readable string describing the given event +proc tag*(event: YamlStreamEvent): TagId {.raises: [FieldError].} + proc startDocEvent*(): YamlStreamEvent {.inline, raises: [].} proc endDocEvent*(): YamlStreamEvent {.inline, raises: [].} proc startMapEvent*(tag: TagId = yTagQuestionMark,