diff --git a/codex/utils/json.nim b/codex/utils/json.nim index a893ce5f..8ece70e0 100644 --- a/codex/utils/json.nim +++ b/codex/utils/json.nim @@ -65,6 +65,13 @@ template expectJsonKind( ) = expectJsonKind(expectedType, {expectedKind}, json) +proc fromJson*( + T: type enum, + json: JsonNode +): ?!T = + expectJsonKind(string, JString, json) + catch parseEnum[T](json.str) + proc fromJson*( _: type string, json: JsonNode @@ -177,7 +184,7 @@ proc fromJson*( json: JsonNode ): ?!Cid = expectJsonKind(Cid, JString, json) - Cid.init($json).mapFailure + Cid.init(json.str).mapFailure proc fromJson*[T]( _: type seq[T], @@ -189,34 +196,16 @@ proc fromJson*[T]( arr.add(? T.fromJson(elem)) success arr -proc fromJson*[T: object]( +proc fromJson*[T: ref object or object]( _: type T, json: JsonNode ): ?!T = expectJsonKind(T, JObject, json) - var res = T.default - # Leave this in, it's good for debugging: - # trace "deserializing object", to = $T, json - for name, value in fieldPairs(res): - if json{name} != nil: - without parsed =? type(value).fromJson(json{name}), e: - error "error deserializing field", - field = $T & "." & name, - json = json{name}, - error = e.msg - return failure(e) - value = parsed - success(res) + var res = when type(T) is ref: T.new() else: T.default -proc fromJson*[T: ref object]( - _: type T, - json: JsonNode -): ?!T = - expectJsonKind(T, JObject, json) - var res = T.new() # Leave this in, it's good for debugging: # trace "deserializing object", to = $T, json - for name, value in fieldPairs(res[]): + for name, value in fieldPairs(when type(T) is ref: res[] else: res): if json{name} != nil: without parsed =? type(value).fromJson(json{name}), e: error "error deserializing field", diff --git a/tests/codex/utils/testjson.nim b/tests/codex/utils/testjson.nim index 059f80ef..edb3cdce 100644 --- a/tests/codex/utils/testjson.nim +++ b/tests/codex/utils/testjson.nim @@ -11,6 +11,7 @@ from pkg/codex/rest/json import RestPurchase import pkg/codex/utils/json as utilsjson import pkg/questionable import pkg/questionable/results +import pkg/libp2p import ../examples import ../helpers @@ -213,6 +214,10 @@ checksuite "json serialization": }""".flatten check request.toJson == expected + test "deserialize enum": + let json = newJString($CidVersion.CIDv1) + check !CidVersion.fromJson(json) == CIDv1 + test "deserializes UInt256 from non-hex string representation": let json = newJString("100000") check !UInt256.fromJson(json) == 100000.u256 @@ -327,6 +332,14 @@ checksuite "json serialization": check deserialized.mystring == expected.mystring check deserialized.myint == expected.myint + test "deserializes Cid": + let + jCid = newJString("zdj7Wakya26ggQWkvMdHYFcPgZ7Qh2HdMooQDDFDHkk4uHS14") + cid = "zdj7Wakya26ggQWkvMdHYFcPgZ7Qh2HdMooQDDFDHkk4uHS14" + + check: + !Cid.fromJson(jCid) == !Cid.init(cid).mapFailure + test "deserializes StorageRequest": check !StorageRequest.fromJson(requestJson) == request