Add support and tests for Option and reference types
This commit is contained in:
parent
a1baedeb1b
commit
9d909d352a
|
@ -102,6 +102,12 @@ proc skipToken(r: var JsonReader, tk: TokKind) =
|
||||||
r.requireToken tk
|
r.requireToken tk
|
||||||
r.lexer.next()
|
r.lexer.next()
|
||||||
|
|
||||||
|
proc allocPtr[T](p: var ptr T) =
|
||||||
|
p = create(T)
|
||||||
|
|
||||||
|
proc allocPtr[T](p: var ref T) =
|
||||||
|
p = new(T)
|
||||||
|
|
||||||
proc readValue*(r: var JsonReader, value: var auto) =
|
proc readValue*(r: var JsonReader, value: var auto) =
|
||||||
mixin readValue
|
mixin readValue
|
||||||
|
|
||||||
|
@ -119,6 +125,14 @@ proc readValue*(r: var JsonReader, value: var auto) =
|
||||||
else: r.raiseUnexpectedToken etBool
|
else: r.raiseUnexpectedToken etBool
|
||||||
r.lexer.next()
|
r.lexer.next()
|
||||||
|
|
||||||
|
elif value is ref|ptr:
|
||||||
|
if tok == tkNull:
|
||||||
|
value = nil
|
||||||
|
r.lexer.next()
|
||||||
|
else:
|
||||||
|
allocPtr value
|
||||||
|
value[] = readValue(r, type(value[]))
|
||||||
|
|
||||||
elif value is enum:
|
elif value is enum:
|
||||||
case tok
|
case tok
|
||||||
of tkString:
|
of tkString:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import std/net, ../../json_serialization.nim
|
import std/net, ../../json_serialization.nim
|
||||||
export json_serialization
|
export net
|
||||||
|
|
||||||
proc writeValue*(writer: var JsonWriter, value: Port) =
|
proc writeValue*(writer: var JsonWriter, value: Port) =
|
||||||
writeValue(writer, uint16 value)
|
writeValue(writer, uint16 value)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import std/options, ../../json_serialization/[reader, writer, lexer]
|
||||||
|
export options
|
||||||
|
|
||||||
|
proc writeValue*(writer: var JsonWriter, value: Option) =
|
||||||
|
if value.isSome:
|
||||||
|
writer.writeValue value.get
|
||||||
|
else:
|
||||||
|
writer.writeValue JsonString("null")
|
||||||
|
|
||||||
|
proc readValue*[T](reader: var JsonReader, value: var Option[T]) =
|
||||||
|
let tok = reader.lexer.tok
|
||||||
|
if tok == tkNull:
|
||||||
|
reset value
|
||||||
|
reader.lexer.next()
|
||||||
|
else:
|
||||||
|
value = some reader.readValue(T)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import
|
import
|
||||||
strutils, options, unittest,
|
strutils, unittest,
|
||||||
serialization/testing/generic_suite,
|
serialization/testing/generic_suite,
|
||||||
../json_serialization, ./utils
|
../json_serialization, ./utils,
|
||||||
|
../json_serialization/std/options
|
||||||
|
|
||||||
type
|
type
|
||||||
Meter = distinct int
|
Meter = distinct int
|
||||||
|
@ -20,7 +21,10 @@ type
|
||||||
Bar = object
|
Bar = object
|
||||||
sf: seq[Foo]
|
sf: seq[Foo]
|
||||||
z: ref Simple
|
z: ref Simple
|
||||||
# o: Option[Simple]
|
|
||||||
|
HoldsOption = object
|
||||||
|
r: ref Simple
|
||||||
|
o: Option[Simple]
|
||||||
|
|
||||||
HoldsArray = object
|
HoldsArray = object
|
||||||
data: seq[int]
|
data: seq[int]
|
||||||
|
@ -37,8 +41,22 @@ template reject(code) =
|
||||||
|
|
||||||
borrowSerialization(Meter, int)
|
borrowSerialization(Meter, int)
|
||||||
|
|
||||||
|
proc `==`(lhs, rhs: Meter): bool =
|
||||||
|
int(lhs) == int(rhs)
|
||||||
|
|
||||||
|
proc `==`(lhs, rhs: ref Simple): bool =
|
||||||
|
if lhs.isNil: return rhs.isNil
|
||||||
|
if rhs.isNil: return false
|
||||||
|
return lhs[] == rhs[]
|
||||||
|
|
||||||
executeReaderWriterTests Json
|
executeReaderWriterTests Json
|
||||||
|
|
||||||
|
proc newSimple(x: int, y: string, d: Meter): ref Simple =
|
||||||
|
new result
|
||||||
|
result.x = x
|
||||||
|
result.y = y
|
||||||
|
result.distance = d
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
# The compiler cannot handle this check at the moment
|
# The compiler cannot handle this check at the moment
|
||||||
# {.fatal.} seems fatal even in `compiles` context
|
# {.fatal.} seems fatal even in `compiles` context
|
||||||
|
@ -111,3 +129,12 @@ suite "toJson tests":
|
||||||
check:
|
check:
|
||||||
r.toJSON == """{"type":"uint8"}"""
|
r.toJSON == """{"type":"uint8"}"""
|
||||||
r == Json.decode("""{"type":"uint8"}""", Reserved)
|
r == Json.decode("""{"type":"uint8"}""", Reserved)
|
||||||
|
|
||||||
|
test "Option types":
|
||||||
|
let
|
||||||
|
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}"""
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue