121 lines
3.4 KiB
Nim
Raw Normal View History

{.push raises: [].}
import
std/[typetraits, parseutils],
results,
stew/[byteutils, base10],
chronicles,
serialization,
json_serialization,
2022-11-04 10:52:08 +01:00
json_serialization/std/options,
json_serialization/std/net,
json_serialization/std/sets,
presto/common
import ../../common/base64
logScope:
topics = "waku node rest"
createJsonFlavor RestJson
Json.setWriter JsonWriter, PreferredOutput = string
template unrecognizedFieldWarning*(field: typed) =
# TODO: There should be a different notification mechanism for informing the
# caller of a deserialization routine for unexpected fields.
# The chonicles import in this module should be removed.
info "JSON field not recognized by the current version of nwaku. Consider upgrading",
fieldName, typeName = typetraits.name(typeof field)
type SerdesResult*[T] = Result[T, cstring]
proc writeValue*(
writer: var JsonWriter, value: Base64String
) {.gcsafe, raises: [IOError].} =
writer.writeValue(string(value))
proc readValue*(
reader: var JsonReader, value: var Base64String
) {.gcsafe, raises: [SerializationError, IOError].} =
value = Base64String(reader.readValue(string))
proc decodeFromJsonString*[T](
t: typedesc[T], data: JsonString, requireAllFields: bool = true
): SerdesResult[T] =
try:
if requireAllFields:
ok(
RestJson.decode(
string(data), T, requireAllFields = true, allowUnknownFields = true
)
)
else:
ok(
RestJson.decode(
string(data), T, requireAllFields = false, allowUnknownFields = true
)
)
except SerializationError:
# TODO: Do better error reporting here
err("Unable to deserialize data")
# Internal static implementation
proc decodeFromJsonBytes*[T](
t: typedesc[T], data: openArray[byte], requireAllFields: bool = true
): SerdesResult[T] =
try:
if requireAllFields:
ok(
RestJson.decode(
string.fromBytes(data), T, requireAllFields = true, allowUnknownFields = true
)
)
else:
ok(
RestJson.decode(
string.fromBytes(data), T, requireAllFields = false, allowUnknownFields = true
)
)
except SerializationError:
err("Unable to deserialize data: " & getCurrentExceptionMsg())
proc encodeIntoJsonString*(value: auto): SerdesResult[string] =
var encoded: string
try:
var stream = memoryOutput()
var writer = JsonWriter[RestJson].init(stream)
writer.writeValue(value)
encoded = stream.getOutput(string)
except SerializationError, IOError:
# TODO: Do better error reporting here
return err("unable to serialize data")
ok(encoded)
proc encodeIntoJsonBytes*(value: auto): SerdesResult[seq[byte]] =
var encoded: seq[byte]
try:
var stream = memoryOutput()
var writer = JsonWriter[RestJson].init(stream)
writer.writeValue(value)
encoded = stream.getOutput(seq[byte])
except SerializationError, IOError:
# TODO: Do better error reporting here
return err("unable to serialize data")
ok(encoded)
#### helpers
proc encodeString*(value: string): SerdesResult[string] =
ok(value)
proc decodeString*(t: typedesc[string], value: string): SerdesResult[string] =
ok(value)
proc encodeString*(value: SomeUnsignedInt): SerdesResult[string] =
ok(Base10.toString(value))
proc decodeString*(T: typedesc[SomeUnsignedInt], value: string): SerdesResult[T] =
return Base10.decode(T, value)