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 =
|
||||
mixin writeFieldIMPL, writeValue
|
||||
|
||||
type
|
||||
R {.used.} = type record
|
||||
|
||||
w.writeFieldName(fieldName)
|
||||
when RecordType is tuple:
|
||||
w.writeValue(field)
|
||||
else:
|
||||
type RR = type record
|
||||
w.writeFieldIMPL(FieldTag[RR, fieldName], field, record)
|
||||
type R = type record
|
||||
w.writeFieldIMPL(FieldTag[R, fieldName], field, record)
|
||||
true
|
||||
|
||||
proc writeRecordValue*(w: var JsonWriter, value: auto)
|
||||
|
@ -179,11 +176,67 @@ proc writeRecordValue*(w: var JsonWriter, value: auto)
|
|||
|
||||
type RecordType = type value
|
||||
w.beginRecord RecordType
|
||||
value.enumInstanceSerializedFields(fieldName, field):
|
||||
if writeObjectField(w, value, fieldName, field):
|
||||
w.state = AfterField
|
||||
value.enumInstanceSerializedFields(fieldName, fieldType):
|
||||
when fieldType isnot JsonVoid:
|
||||
if writeObjectField(w, value, fieldName, fieldType):
|
||||
w.state = AfterField
|
||||
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].} =
|
||||
mixin writeValue
|
||||
|
||||
|
@ -194,6 +247,15 @@ proc writeValue*(w: var JsonWriter, value: auto) {.gcsafe, raises: [IOError].} =
|
|||
elif value is JsonString:
|
||||
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:
|
||||
if value == nil:
|
||||
append "null"
|
||||
|
|
|
@ -45,11 +45,34 @@ type
|
|||
one: Opt[string]
|
||||
two: Option[int]
|
||||
|
||||
SpecialTypes = object
|
||||
one: JsonVoid
|
||||
two: JsonNumber[uint64]
|
||||
three: JsonNumber[string]
|
||||
four: JsonValueRef[uint64]
|
||||
|
||||
Container.useDefaultSerializationIn StringyJson
|
||||
|
||||
createJsonFlavor 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":
|
||||
test "basic test":
|
||||
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)
|
||||
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