Handle changes in the serialization APIs
This commit is contained in:
parent
7922a83c4d
commit
73d9e0d458
|
@ -17,10 +17,6 @@ type
|
|||
encounteredField*: cstring
|
||||
deserializedType*: cstring
|
||||
|
||||
CustomSerializationError* = object of JsonReaderError
|
||||
deserializedField*: string
|
||||
innerException*: ref CatchableError
|
||||
|
||||
ExpectedTokenCategory* = enum
|
||||
etBool = "bool literal"
|
||||
etInt = "integer"
|
||||
|
@ -33,6 +29,10 @@ type
|
|||
etCurrlyLe = "object start bracket"
|
||||
etCurrlyRi = "object end bracket"
|
||||
|
||||
GenericJsonReaderError* = object of JsonReaderError
|
||||
deserializedField*: string
|
||||
innerException*: ref CatchableError
|
||||
|
||||
UnexpectedToken* = object of JsonReaderError
|
||||
encountedToken*: TokKind
|
||||
expectedToken*: ExpectedTokenCategory
|
||||
|
@ -46,8 +46,8 @@ method formatMsg*(err: ref UnexpectedField, filename: string): string =
|
|||
method formatMsg*(err: ref UnexpectedToken, filename: string): string =
|
||||
fmt"{filename}({err.line}, {err.col}) Unexpected token '{err.encountedToken}' in place of '{err.expectedToken}'"
|
||||
|
||||
method formatMsg*(err: ref CustomSerializationError, filename: string): string =
|
||||
fmt"{filename}({err.line}, {err.col}) Custom serialization exception while deserializing '{err.deserializedField}': [{err.innerException.name}] {err.innerException.msg}"
|
||||
method formatMsg*(err: ref GenericJsonReaderError, filename: string): string =
|
||||
fmt"{filename}({err.line}, {err.col}) Exception encountered while deserializing '{err.deserializedField}': [{err.innerException.name}] {err.innerException.msg}"
|
||||
|
||||
template init*(T: type JsonReader, stream: ByteStreamVar, mode = defaultJsonMode): auto =
|
||||
init JsonReader, AsciiStreamVar(stream), mode
|
||||
|
@ -70,10 +70,12 @@ proc raiseUnexpectedField(r: JsonReader, fieldName, deserializedType: cstring) =
|
|||
ex.deserializedType = deserializedType
|
||||
raise ex
|
||||
|
||||
proc readValueFailed*(r: JsonReader,
|
||||
Record: type, fieldName: string, field: var auto,
|
||||
err: ref CatchableError) =
|
||||
var ex = new CustomSerializationError
|
||||
proc handleReadException*(r: JsonReader,
|
||||
Record: type,
|
||||
fieldName: string,
|
||||
field: var auto,
|
||||
err: ref CatchableError) =
|
||||
var ex = new GenericJsonReaderError
|
||||
ex.assignLineNumber(r)
|
||||
ex.deserializedField = fieldName
|
||||
ex.innerException = err
|
||||
|
|
|
@ -125,6 +125,8 @@ proc writeArray[T](w: var JsonWriter, elements: openarray[T]) =
|
|||
writeIterable(w, elements)
|
||||
|
||||
proc writeValue*(w: var JsonWriter, value: auto) =
|
||||
mixin enumInstanceSerializedFields
|
||||
|
||||
template addChar(c) =
|
||||
append c
|
||||
|
||||
|
@ -161,7 +163,6 @@ proc writeValue*(w: var JsonWriter, value: auto) =
|
|||
# TODO: Should this really use a decimal representation?
|
||||
# Or perhaps $ord(c) returns hex?
|
||||
# This is potentially a bug in Nim's json module.
|
||||
# In any case, we can call appendNumber here.
|
||||
append $ord(c)
|
||||
of '\\': addPrefixSlash '\\'
|
||||
else: addChar c
|
||||
|
@ -170,16 +171,16 @@ proc writeValue*(w: var JsonWriter, value: auto) =
|
|||
elif value is bool:
|
||||
append if value: "true" else: "false"
|
||||
elif value is enum:
|
||||
w.stream.appendNumber ord(value)
|
||||
w.stream.append $ord(value)
|
||||
elif value is SomeInteger:
|
||||
w.stream.appendNumber value
|
||||
w.stream.append $value
|
||||
elif value is SomeFloat:
|
||||
append $value
|
||||
elif value is (seq or array):
|
||||
w.writeArray(value)
|
||||
elif value is (object or tuple):
|
||||
w.beginRecord(type(value))
|
||||
value.serializeFields(k, v):
|
||||
value.enumInstanceSerializedFields(k, v):
|
||||
w.writeField k, v
|
||||
w.endRecord()
|
||||
else:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import
|
||||
strutils, unittest,
|
||||
serialization/object_serialization,
|
||||
serialization/testing/generic_suite,
|
||||
../json_serialization, ./utils,
|
||||
../json_serialization/std/[options, sets]
|
||||
|
@ -12,10 +13,11 @@ type
|
|||
x: int
|
||||
y: string
|
||||
distance: Meter
|
||||
ignored: int
|
||||
|
||||
Foo = object
|
||||
i: int
|
||||
b: Bar
|
||||
b {.dontSerialize.}: Bar
|
||||
s: string
|
||||
|
||||
Bar = object
|
||||
|
@ -41,6 +43,8 @@ template reject(code) =
|
|||
|
||||
borrowSerialization(Meter, int)
|
||||
|
||||
Simple.setSerializedFields distance, x, y
|
||||
|
||||
proc `==`(lhs, rhs: Meter): bool =
|
||||
int(lhs) == int(rhs)
|
||||
|
||||
|
@ -74,21 +78,21 @@ suite "toJson tests":
|
|||
var s = Simple(x: 10, y: "test", distance: Meter(20))
|
||||
|
||||
check:
|
||||
s.toJson == """{"x":10,"y":"test","distance":20}"""
|
||||
s.toJson(typeAnnotations = true) == """{"$type":"Simple","x":10,"y":"test","distance":20}"""
|
||||
s.toJson == """{"distance":20,"x":10,"y":"test"}"""
|
||||
s.toJson(typeAnnotations = true) == """{"$type":"Simple","distance":20,"x":10,"y":"test"}"""
|
||||
s.toJson(pretty = true) == dedent"""
|
||||
{
|
||||
"distance": 20,
|
||||
"x": 10,
|
||||
"y": "test",
|
||||
"distance": 20
|
||||
"y": "test"
|
||||
}
|
||||
"""
|
||||
|
||||
test "handle missing fields":
|
||||
let json = dedent"""
|
||||
{
|
||||
"y": "test",
|
||||
"distance": 20
|
||||
"distance": 20,
|
||||
"y": "test"
|
||||
}
|
||||
"""
|
||||
|
||||
|
@ -135,8 +139,8 @@ suite "toJson tests":
|
|||
h1 = HoldsOption(o: some Simple(x: 1, y: "2", distance: Meter(3)))
|
||||
h2 = HoldsOption(r: newSimple(1, "2", Meter(3)))
|
||||
|
||||
Json.roundtripTest h1, """{"r":null,"o":{"x":1,"y":"2","distance":3}}"""
|
||||
Json.roundtripTest h2, """{"r":{"x":1,"y":"2","distance":3},"o":null}"""
|
||||
Json.roundtripTest h1, """{"r":null,"o":{"distance":3,"x":1,"y":"2"}}"""
|
||||
Json.roundtripTest h2, """{"r":{"distance":3,"x":1,"y":"2"},"o":null}"""
|
||||
|
||||
test "Set types":
|
||||
type HoldsSet = object
|
||||
|
|
Loading…
Reference in New Issue