2024-06-28 16:04:57 +05:30
|
|
|
{.push raises: [].}
|
2022-06-02 11:45:00 +02:00
|
|
|
|
2023-11-14 16:59:53 +01:00
|
|
|
import
|
2025-04-24 08:36:02 +02:00
|
|
|
std/[typetraits, parseutils],
|
2024-07-09 13:14:28 +02:00
|
|
|
results,
|
2025-04-24 08:36:02 +02:00
|
|
|
stew/[byteutils, base10],
|
2022-06-02 11:45:00 +02:00
|
|
|
chronicles,
|
|
|
|
|
serialization,
|
|
|
|
|
json_serialization,
|
2022-11-04 10:52:08 +01:00
|
|
|
json_serialization/std/options,
|
|
|
|
|
json_serialization/std/net,
|
|
|
|
|
json_serialization/std/sets,
|
2022-06-02 11:45:00 +02:00
|
|
|
presto/common
|
2024-03-16 00:08:47 +01:00
|
|
|
import ../../common/base64
|
2023-11-14 16:59:53 +01:00
|
|
|
|
|
|
|
|
logScope:
|
2022-11-03 16:36:24 +01:00
|
|
|
topics = "waku node rest"
|
2022-06-02 11:45:00 +02:00
|
|
|
|
2024-01-04 17:35:00 +01:00
|
|
|
createJsonFlavor RestJson
|
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
Json.setWriter JsonWriter, PreferredOutput = string
|
2022-06-02 11:45:00 +02:00
|
|
|
|
2024-12-10 14:42:54 +01:00
|
|
|
template unrecognizedFieldWarning*(field: typed) =
|
2022-06-02 11:45:00 +02:00
|
|
|
# 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.
|
2025-10-15 10:49:36 +02:00
|
|
|
info "JSON field not recognized by the current version of nwaku. Consider upgrading",
|
2024-12-10 14:42:54 +01:00
|
|
|
fieldName, typeName = typetraits.name(typeof field)
|
2022-06-02 11:45:00 +02:00
|
|
|
|
|
|
|
|
type SerdesResult*[T] = Result[T, cstring]
|
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
proc writeValue*(
|
|
|
|
|
writer: var JsonWriter, value: Base64String
|
|
|
|
|
) {.gcsafe, raises: [IOError].} =
|
2024-01-04 17:35:00 +01:00
|
|
|
writer.writeValue(string(value))
|
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
proc readValue*(
|
|
|
|
|
reader: var JsonReader, value: var Base64String
|
|
|
|
|
) {.gcsafe, raises: [SerializationError, IOError].} =
|
2024-01-04 17:35:00 +01:00
|
|
|
value = Base64String(reader.readValue(string))
|
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
proc decodeFromJsonString*[T](
|
2025-09-10 13:20:37 +05:30
|
|
|
t: typedesc[T], data: JsonString, requireAllFields: bool = true
|
2024-03-16 00:08:47 +01:00
|
|
|
): SerdesResult[T] =
|
2022-06-02 11:45:00 +02:00
|
|
|
try:
|
2025-09-10 13:20:37 +05:30
|
|
|
if requireAllFields:
|
|
|
|
|
ok(
|
|
|
|
|
RestJson.decode(
|
|
|
|
|
string(data), T, requireAllFields = true, allowUnknownFields = true
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
ok(
|
|
|
|
|
RestJson.decode(
|
|
|
|
|
string(data), T, requireAllFields = false, allowUnknownFields = true
|
|
|
|
|
)
|
2024-03-16 00:08:47 +01:00
|
|
|
)
|
2022-06-02 11:45:00 +02:00
|
|
|
except SerializationError:
|
|
|
|
|
# TODO: Do better error reporting here
|
|
|
|
|
err("Unable to deserialize data")
|
|
|
|
|
|
2025-09-10 13:20:37 +05:30
|
|
|
# Internal static implementation
|
2024-03-16 00:08:47 +01:00
|
|
|
proc decodeFromJsonBytes*[T](
|
2025-09-10 13:20:37 +05:30
|
|
|
t: typedesc[T], data: openArray[byte], requireAllFields: bool = true
|
2024-03-16 00:08:47 +01:00
|
|
|
): SerdesResult[T] =
|
2022-06-02 11:45:00 +02:00
|
|
|
try:
|
2025-09-10 13:20:37 +05:30
|
|
|
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
|
|
|
|
|
)
|
2024-03-16 00:08:47 +01:00
|
|
|
)
|
2022-06-02 11:45:00 +02:00
|
|
|
except SerializationError:
|
2025-02-14 11:14:38 +01:00
|
|
|
err("Unable to deserialize data: " & getCurrentExceptionMsg())
|
2022-06-02 11:45:00 +02:00
|
|
|
|
|
|
|
|
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")
|
|
|
|
|
|
2022-06-10 13:30:51 +02:00
|
|
|
ok(encoded)
|
|
|
|
|
|
|
|
|
|
#### helpers
|
|
|
|
|
|
2025-09-10 13:20:37 +05:30
|
|
|
proc encodeString*(value: string): SerdesResult[string] =
|
2022-06-10 13:30:51 +02:00
|
|
|
ok(value)
|
|
|
|
|
|
2025-09-10 13:20:37 +05:30
|
|
|
proc decodeString*(t: typedesc[string], value: string): SerdesResult[string] =
|
2022-06-10 13:30:51 +02:00
|
|
|
ok(value)
|
2025-04-24 08:36:02 +02:00
|
|
|
|
2025-09-10 13:20:37 +05:30
|
|
|
proc encodeString*(value: SomeUnsignedInt): SerdesResult[string] =
|
2025-04-24 08:36:02 +02:00
|
|
|
ok(Base10.toString(value))
|
|
|
|
|
|
2025-09-10 13:20:37 +05:30
|
|
|
proc decodeString*(T: typedesc[SomeUnsignedInt], value: string): SerdesResult[T] =
|
2025-10-27 14:07:06 -03:00
|
|
|
return Base10.decode(T, value)
|