From e89a9a5b142a60a36a81a8f6dffe9e83d545b30e Mon Sep 17 00:00:00 2001 From: Felix Krause Date: Mon, 1 Feb 2016 20:16:35 +0100 Subject: [PATCH] Serialization: Support enum types --- README.md | 3 +-- test/serializing.nim | 22 ++++++++++++++++++++++ yaml/serialization.nim | 23 ++++++++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 47fd510..6329755 100644 --- a/README.md +++ b/README.md @@ -212,8 +212,7 @@ Output: - Add type hints for more scalar types * Serialization: - Support for more standard library types - - Support for enum types - - Support polymorphism (requires ref and ptr types) + - Support polymorphism - Support variant objects - Support transient fields (i.e. fields that will not be (de-)serialized on objects and tuples) diff --git a/test/serializing.nim b/test/serializing.nim index ba53e3a..346da4e 100644 --- a/test/serializing.nim +++ b/test/serializing.nim @@ -7,6 +7,9 @@ type i: int32 b: bool + TrafficLight = enum + tlGreen, tlYellow, tlRed + Person = object firstname, surname: string age: int32 @@ -89,6 +92,25 @@ suite "Serialization": assertStringEqual "%YAML 1.2\n--- \n- [1, 2, 3]\n- [4, 5]\n- [6]", output.data + test "Serialization: Load Enum": + let input = newStringStream("- tlRed\n- tlGreen\n- tlYellow") + var + result: seq[TrafficLight] + parser = newYamlParser(tagLib) + events = parser.parse(input) + construct(events, result) + assert result.len == 3 + assert result[0] == tlRed + assert result[1] == tlGreen + assert result[2] == tlYellow + + test "Serialization: Serialize Enum": + let input = @[tlRed, tlGreen, tlYellow] + var output = newStringStream() + dump(input, output, psBlockOnly, tsNone) + assertStringEqual "%YAML 1.2\n--- \n- tlRed\n- tlGreen\n- tlYellow", + output.data + test "Serialization: Load Tuple": let input = newStringStream("str: value\ni: 42\nb: true") var diff --git a/yaml/serialization.nim b/yaml/serialization.nim index 4298b07..e108ebc 100644 --- a/yaml/serialization.nim +++ b/yaml/serialization.nim @@ -605,7 +605,7 @@ proc serializeObject*[K, V](value: Table[K, V], ts: TagStyle, yield event yield YamlStreamEvent(kind: yamlEndMap) -template yamlTag*(T: typedesc[object]): expr = +template yamlTag*(T: typedesc[object|enum]): expr = var uri = when compiles(yamlTagId(T)): yamlTagId(T) else: "!nim:custom:" & T.name try: @@ -663,6 +663,27 @@ proc serializeObject*[O: object|tuple](value: O, ts: TagStyle, yield event yield endMapEvent() +proc constructObject*[O: enum](s: YamlStream, c: ConstructionContext, + result: var O) + {.raises: [YamlConstructionError, YamlConstructionStreamError].} = + let e = s() + assert(not finished(s)) + if e.kind != yamlScalar: + raise newException(YamlConstructionError, "Expected scalar, got " & + $e.kind) + try: result = parseEnum[O](e.scalarContent) + except ValueError: + var ex = newException(YamlConstructionError, "Cannot parse '" & + e.scalarContent & "' as " & type(O).name) + ex.parent = getCurrentException() + raise ex + +proc serializeObject*[O: enum](value: O, ts: TagStyle, + c: SerializationContext): + YamlStream {.raises: [].} = + result = iterator(): YamlStreamEvent = + yield scalarEvent($value, presentTag(O, ts), yAnchorNone) + proc yamlTag*[O](T: typedesc[ref O]): TagId {.inline, raises: [].} = yamlTag(O) proc constructObject*[O](s: YamlStream, c: ConstructionContext,