Add JsonVoid, JsonNumber, and JsonValueRef to JsonWriter
This commit is contained in:
parent
9720b33f99
commit
61a03e20d3
|
@ -162,15 +162,12 @@ template writeObjectField*[FieldType, RecordType](w: var JsonWriter,
|
||||||
field: FieldType): bool =
|
field: FieldType): bool =
|
||||||
mixin writeFieldIMPL, writeValue
|
mixin writeFieldIMPL, writeValue
|
||||||
|
|
||||||
type
|
|
||||||
R {.used.} = type record
|
|
||||||
|
|
||||||
w.writeFieldName(fieldName)
|
w.writeFieldName(fieldName)
|
||||||
when RecordType is tuple:
|
when RecordType is tuple:
|
||||||
w.writeValue(field)
|
w.writeValue(field)
|
||||||
else:
|
else:
|
||||||
type RR = type record
|
type R = type record
|
||||||
w.writeFieldIMPL(FieldTag[RR, fieldName], field, record)
|
w.writeFieldIMPL(FieldTag[R, fieldName], field, record)
|
||||||
true
|
true
|
||||||
|
|
||||||
proc writeRecordValue*(w: var JsonWriter, value: auto)
|
proc writeRecordValue*(w: var JsonWriter, value: auto)
|
||||||
|
@ -179,11 +176,67 @@ proc writeRecordValue*(w: var JsonWriter, value: auto)
|
||||||
|
|
||||||
type RecordType = type value
|
type RecordType = type value
|
||||||
w.beginRecord RecordType
|
w.beginRecord RecordType
|
||||||
value.enumInstanceSerializedFields(fieldName, field):
|
value.enumInstanceSerializedFields(fieldName, fieldType):
|
||||||
if writeObjectField(w, value, fieldName, field):
|
when fieldType isnot JsonVoid:
|
||||||
|
if writeObjectField(w, value, fieldName, fieldType):
|
||||||
w.state = AfterField
|
w.state = AfterField
|
||||||
w.endRecord()
|
w.endRecord()
|
||||||
|
|
||||||
|
proc writeNumber*[F,T](w: var JsonWriter[F], value: JsonNumber[T]) =
|
||||||
|
if value.sign == JsonSign.Neg:
|
||||||
|
append '-'
|
||||||
|
|
||||||
|
when T is uint64:
|
||||||
|
w.stream.writeText value.integer
|
||||||
|
else:
|
||||||
|
append value.integer
|
||||||
|
|
||||||
|
if value.fraction.len > 0:
|
||||||
|
append '.'
|
||||||
|
append value.fraction
|
||||||
|
|
||||||
|
template writeExp(body: untyped) =
|
||||||
|
when T is uint64:
|
||||||
|
if value.exponent > 0:
|
||||||
|
body
|
||||||
|
else:
|
||||||
|
if value.exponent.len > 0:
|
||||||
|
body
|
||||||
|
|
||||||
|
writeExp:
|
||||||
|
append 'e'
|
||||||
|
if value.sign == JsonSign.Neg:
|
||||||
|
append '-'
|
||||||
|
when T is uint64:
|
||||||
|
w.stream.writeText value.exponent
|
||||||
|
else:
|
||||||
|
append value.exponent
|
||||||
|
|
||||||
|
proc writeJsonValueRef*[F,T](w: var JsonWriter[F], value: JsonValueRef[T]) =
|
||||||
|
if value.isNil:
|
||||||
|
append "null"
|
||||||
|
return
|
||||||
|
|
||||||
|
case value.kind
|
||||||
|
of JsonValueKind.String:
|
||||||
|
w.writeValue(value.strVal)
|
||||||
|
of JsonValueKind.Number:
|
||||||
|
w.writeNumber(value.numVal)
|
||||||
|
of JsonValueKind.Object:
|
||||||
|
w.beginRecord typeof(value)
|
||||||
|
for k, v in value.objVal:
|
||||||
|
w.writeField(k, v)
|
||||||
|
w.endRecord()
|
||||||
|
of JsonValueKind.Array:
|
||||||
|
w.writeArray(value.arrayVal)
|
||||||
|
of JsonValueKind.Bool:
|
||||||
|
if value.boolVal:
|
||||||
|
append "true"
|
||||||
|
else:
|
||||||
|
append "false"
|
||||||
|
of JsonValueKind.Null:
|
||||||
|
append "null"
|
||||||
|
|
||||||
proc writeValue*(w: var JsonWriter, value: auto) {.gcsafe, raises: [IOError].} =
|
proc writeValue*(w: var JsonWriter, value: auto) {.gcsafe, raises: [IOError].} =
|
||||||
mixin writeValue
|
mixin writeValue
|
||||||
|
|
||||||
|
@ -194,6 +247,15 @@ proc writeValue*(w: var JsonWriter, value: auto) {.gcsafe, raises: [IOError].} =
|
||||||
elif value is JsonString:
|
elif value is JsonString:
|
||||||
append string(value)
|
append string(value)
|
||||||
|
|
||||||
|
elif value is JsonVoid:
|
||||||
|
discard
|
||||||
|
|
||||||
|
elif value is JsonNumber:
|
||||||
|
w.writeNumber(value)
|
||||||
|
|
||||||
|
elif value is JsonValueRef:
|
||||||
|
w.writeJsonValueRef(value)
|
||||||
|
|
||||||
elif value is ref:
|
elif value is ref:
|
||||||
if value == nil:
|
if value == nil:
|
||||||
append "null"
|
append "null"
|
||||||
|
|
|
@ -45,11 +45,34 @@ type
|
||||||
one: Opt[string]
|
one: Opt[string]
|
||||||
two: Option[int]
|
two: Option[int]
|
||||||
|
|
||||||
|
SpecialTypes = object
|
||||||
|
one: JsonVoid
|
||||||
|
two: JsonNumber[uint64]
|
||||||
|
three: JsonNumber[string]
|
||||||
|
four: JsonValueRef[uint64]
|
||||||
|
|
||||||
Container.useDefaultSerializationIn StringyJson
|
Container.useDefaultSerializationIn StringyJson
|
||||||
|
|
||||||
createJsonFlavor OptJson
|
createJsonFlavor OptJson
|
||||||
OptionalFields.useDefaultSerializationIn OptJson
|
OptionalFields.useDefaultSerializationIn OptJson
|
||||||
|
|
||||||
|
const
|
||||||
|
jsonText = """
|
||||||
|
{
|
||||||
|
"one": "this text will gone",
|
||||||
|
"two": -789.0009E-19,
|
||||||
|
"three": 999.776000E+33,
|
||||||
|
"four" : {
|
||||||
|
"apple": [1, true, "three"],
|
||||||
|
"banana": {
|
||||||
|
"chip": 123,
|
||||||
|
"z": null,
|
||||||
|
"v": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
suite "Test JsonFlavor":
|
suite "Test JsonFlavor":
|
||||||
test "basic test":
|
test "basic test":
|
||||||
let c = Container(name: "c", x: -10, y: 20, list: @[1'i64, 2, 25])
|
let c = Container(name: "c", x: -10, y: 20, list: @[1'i64, 2, 25])
|
||||||
|
@ -72,3 +95,12 @@ suite "Test JsonFlavor":
|
||||||
|
|
||||||
let cc = OptJson.encode(c)
|
let cc = OptJson.encode(c)
|
||||||
check cc == """{"one":"burn","two":333}"""
|
check cc == """{"one":"burn","two":333}"""
|
||||||
|
|
||||||
|
test "Write special types":
|
||||||
|
let vv = Json.decode(jsonText, SpecialTypes)
|
||||||
|
let xx = Json.encode(vv)
|
||||||
|
var ww = Json.decode(xx, SpecialTypes)
|
||||||
|
ww.three.expSign = JsonSign.Pos # the rest of it should identical to vv
|
||||||
|
check:
|
||||||
|
ww == vv
|
||||||
|
xx == """{"two":-789.0009e-19,"three":999.776000e33,"four":{"apple":[1,true,"three"],"banana":{"chip":123,"z":null,"v":false}}}"""
|
||||||
|
|
Loading…
Reference in New Issue