mirror of
https://github.com/status-im/nim-json-serialization.git
synced 2026-08-31 02:41:06 +00:00
An implementation of https://github.com/status-im/nim-json-serialization/issues/112 that introduces `beginArray`/`endArray` for the streaming creation of arrays. In order to accomodate the need for intra-element plumbing, we add `begin`/`end` marker calls to the `writeValue` implementation which helps the writer keep track of each value being written and therefore allows it to inject the correct delimiters and indents. Here's an example of writing a `writeValue` overload that writes an array nested in an object: ```nim proc writeValue(w: var JsonWriter, t: MyType) = w.beginArray() for i in 0 ..< t.children: writer.beginObject() writer.writeMember("id", i) writer.writeMember("name", "item" & t.childName[i]) writer.endObject() writer.endArray() ``` Similar to the existing `beginRecord`/`endRecord` fields we add `beginArray` and `endArray` - we also take the opportunity to name `beginObject` according to its json-spec-derived name. The old name remains available. This change introduces a backwards-compatibility break for custom writers that try to access the stream directly: they now have to delimit their value writing with `w.streamElement(s): s.write ...` where `s` is the stream variable. The block template enforces begin/end markers on behalf of the writer. Further examples are available in the documentation. With this change, we also deprecate workarounds like `fieldWritten` and `endRecordField` since a regular replacement exists in the form of consistent begin/end pairs. * doc fixes * make beginElement/endElement private Should not be called directly as `writeValue` / `streamElement` take care of it.
67 lines
1.6 KiB
Nim
67 lines
1.6 KiB
Nim
import std/json, json_serialization
|
|
|
|
# ANCHOR: Decode
|
|
const rawJson = """{"name": "localhost", "port": 42}"""
|
|
type
|
|
NimServer = object
|
|
name: string
|
|
port: int
|
|
|
|
MixedServer = object
|
|
name: JsonValueRef[uint64]
|
|
port: int
|
|
|
|
StringServer = object
|
|
name: JsonString
|
|
port: JsonString
|
|
|
|
var conf = defaultJsonReaderConf
|
|
conf.nestedDepthLimit = 0
|
|
|
|
# decode into native Nim
|
|
let native = Json.decode(rawJson, NimServer)
|
|
|
|
# decode into mixed Nim + JsonValueRef
|
|
let mixed = Json.decode(rawJson, MixedServer)
|
|
|
|
# decode any value into nested json string
|
|
let str = Json.decode(rawJson, StringServer)
|
|
|
|
# decode any valid JSON, using the `json_serialization` node type
|
|
let value = Json.decode(rawJson, JsonValueRef[uint64])
|
|
|
|
# decode any valid JSON, using the `std/json` node type
|
|
let stdjson = Json.decode(rawJson, JsonNode)
|
|
|
|
# read JSON document from file instead
|
|
let file = Json.loadFile("filename.json", NimServer)
|
|
# ANCHOR_END: Decode
|
|
|
|
# ANCHOR: Reader
|
|
var reader = JsonReader[DefaultFlavor].init(memoryInput(rawJson))
|
|
let native2 = reader.readValue(NimServer)
|
|
|
|
# Overwrite an existing instance
|
|
var reader2 = JsonReader[DefaultFlavor].init(memoryInput(rawJson))
|
|
var native3: NimServer
|
|
reader2.readValue(native3)
|
|
# ANCHOR_END: Reader
|
|
|
|
# ANCHOR: Encode
|
|
# Convert object to string
|
|
echo Json.encode(native)
|
|
|
|
# Write JSON to file
|
|
Json.saveFile("filename.json", native)
|
|
|
|
# Pretty-print a tuple
|
|
echo Json.encode((x: 4, y: 5), pretty = true)
|
|
# ANCHOR_END: Encode
|
|
|
|
# ANCHOR: Writer
|
|
var output = memoryOutput()
|
|
var writer = JsonWriter[DefaultFlavor].init(output)
|
|
writer.writeValue(native)
|
|
echo output.getOutput(string)
|
|
# ANCHOR_END: Writer
|