diff --git a/serde.nim b/serde.nim index aa90a81..11a6e99 100644 --- a/serde.nim +++ b/serde.nim @@ -1,5 +1,13 @@ -import ./serde/serialize -import ./serde/deserialize +import ./serde/common +import ./serde/deserializer +import ./serde/json +import ./serde/pragmas +import ./serde/serializer +import ./serde/types -export serialize -export deserialize +export common +export deserializer +export json +export pragmas +export serializer +export types diff --git a/serde.nimble b/serde.nimble index d4c2385..a37961a 100644 --- a/serde.nimble +++ b/serde.nimble @@ -4,7 +4,7 @@ version = "0.1.0" author = "nim-json authors" description = "Drop-in replacement for std/json, with easy-to-use json serialization capabilities." license = "MIT" -srcDir = "src" +skipDirs = @["tests"] # Dependencies diff --git a/serde/common.nim b/serde/common.nim index 14cf33b..2228728 100644 --- a/serde/common.nim +++ b/serde/common.nim @@ -1,16 +1,11 @@ -import std/json as stdjson except `%`, `%*` +import std/json as stdjson -import pkg/questionable import pkg/questionable/results -export stdjson except `%`, `%*`, parseJson +import ./types {.push raises: [].} -type - SerdeError* = object of CatchableError - JsonParseError* = object of SerdeError - proc parseJson*(json: string): ?!JsonNode = ## fix for nim raising Exception try: diff --git a/serde/deserialize.nim b/serde/deserializer.nim similarity index 87% rename from serde/deserialize.nim rename to serde/deserializer.nim index de1aa40..987c5d9 100644 --- a/serde/deserialize.nim +++ b/serde/deserializer.nim @@ -1,5 +1,4 @@ -# import std/json as stdjson except `%`, `%*` import std/macros import std/options import std/sequtils @@ -13,13 +12,17 @@ import pkg/stint import pkg/questionable import pkg/questionable/results -import ./common # parseJson, std/json except `%`, `%*` +import ./common +import ./errors +import ./json import ./pragmas import ./types export common export chronicles except toJson +export json export pragmas +export results export sets export types @@ -28,41 +31,6 @@ export types logScope: topics = "json deserialization" -proc mapErrTo[E1: ref CatchableError, E2: SerdeError]( - e1: E1, - _: type E2, - msg: string = e1.msg): ref E2 = - - return newException(E2, msg, e1) - -proc newSerdeError(msg: string): ref SerdeError = - newException(SerdeError, msg) - -proc newUnexpectedKindError( - expectedType: type, - expectedKinds: string, - json: JsonNode -): ref UnexpectedKindError = - let kind = if json.isNil: "nil" - else: $json.kind - newException(UnexpectedKindError, - "deserialization to " & $expectedType & " failed: expected " & - expectedKinds & " but got " & $kind) - -proc newUnexpectedKindError( - expectedType: type, - expectedKinds: set[JsonNodeKind], - json: JsonNode -): ref UnexpectedKindError = - newUnexpectedKindError(expectedType, $expectedKinds, json) - -proc newUnexpectedKindError( - expectedType: type, - expectedKind: JsonNodeKind, - json: JsonNode -): ref UnexpectedKindError = - newUnexpectedKindError(expectedType, {expectedKind}, json) - template expectJsonKind( expectedType: type, expectedKinds: set[JsonNodeKind], @@ -269,7 +237,7 @@ proc fromJson*[T: ref object or object]( of OptOut: if opts.ignore: - debug "object field is opted out of deserialization ('igore' is set), skipping" + debug "object field is opted out of deserialization ('ignore' is set), skipping" skip = true elif hasDeserializePragma and opts.key == name: warn "object field marked as deserialize in OptOut mode, but 'ignore' not set, field will be deserialized" diff --git a/serde/errors.nim b/serde/errors.nim new file mode 100644 index 0000000..db6bc57 --- /dev/null +++ b/serde/errors.nim @@ -0,0 +1,41 @@ +from std/json import JsonNode, JsonNodeKind +import std/sets + +import ./types + +{.push raises: [].} + +proc mapErrTo*[E1: ref CatchableError, E2: SerdeError]( + e1: E1, + _: type E2, + msg: string = e1.msg): ref E2 = + + return newException(E2, msg, e1) + +proc newSerdeError*(msg: string): ref SerdeError = + newException(SerdeError, msg) + +proc newUnexpectedKindError*( + expectedType: type, + expectedKinds: string, + json: JsonNode): ref UnexpectedKindError = + + let kind = if json.isNil: "nil" + else: $json.kind + newException(UnexpectedKindError, + "deserialization to " & $expectedType & " failed: expected " & + expectedKinds & " but got " & $kind) + +proc newUnexpectedKindError*( + expectedType: type, + expectedKinds: set[JsonNodeKind], + json: JsonNode): ref UnexpectedKindError = + + newUnexpectedKindError(expectedType, $expectedKinds, json) + +proc newUnexpectedKindError*( + expectedType: type, + expectedKind: JsonNodeKind, + json: JsonNode): ref UnexpectedKindError = + + newUnexpectedKindError(expectedType, {expectedKind}, json) diff --git a/serde/json.nim b/serde/json.nim new file mode 100644 index 0000000..1adde16 --- /dev/null +++ b/serde/json.nim @@ -0,0 +1,3 @@ +import std/json except `%`, `%*`, parseJson + +export json except `%`, `%*`, parseJson diff --git a/serde/pragmas.nim b/serde/pragmas.nim index 4faa74c..caa8c15 100644 --- a/serde/pragmas.nim +++ b/serde/pragmas.nim @@ -2,19 +2,17 @@ import std/macros import ./types -type - SerdeFieldOptions* = object - key*: string - ignore*: bool +export types + +{.push raises: [].} template serialize*(key = "", ignore = false, mode = SerdeMode.OptOut) {.pragma.} template deserialize*(key = "", ignore = false, mode = SerdeMode.OptOut) {.pragma.} proc isDefault[T](paramValue: T): bool {.compileTime.} = - var result = paramValue == T.default when T is SerdeMode: return paramValue == SerdeMode.OptOut - return result + else: return paramValue == T.default template expectMissingPragmaParam*(value, pragma, name, msg) = static: @@ -64,8 +62,6 @@ template getSerdeMode*(T, pragma): SerdeMode = # Type is annotated, mode defaults to OptIn for serialization and OptOut # for deserialization when astToStr(pragma) == "serialize": - static: echo "decided default mode for ", T, "serialize, OptIn" SerdeMode.OptIn elif astToStr(pragma) == "deserialize": - static: echo "decided default mode for ", T, " deserialize, OptOut" - SerdeMode.OptOut \ No newline at end of file + SerdeMode.OptOut diff --git a/serde/serialize.nim b/serde/serializer.nim similarity index 95% rename from serde/serialize.nim rename to serde/serializer.nim index 09e7f94..06907fe 100644 --- a/serde/serialize.nim +++ b/serde/serializer.nim @@ -1,7 +1,5 @@ -# import std/json as stdjson except `%`, `%*` import std/macros import std/options -import std/sets import std/strutils import std/tables import std/typetraits @@ -11,15 +9,13 @@ import pkg/questionable import pkg/stew/byteutils import pkg/stint -import ./common +import ./json import ./pragmas import ./types -# export stdjson except `%`, `%*`, parseJson export chronicles except toJson -export common +export json export pragmas -export sets export types {.push raises: [].} @@ -85,7 +81,6 @@ proc `%`*[T: object or ref object](obj: T): JsonNode = let opts = getSerdeFieldOptions(serialize, name, value) let hasSerialize = value.hasCustomPragma(serialize) - echo T, " hasSerialize: ", hasSerialize var skip = false # workaround for 'continue' not supported in a 'fields' loop case mode: diff --git a/serde/types.nim b/serde/types.nim index 2a5c1f0..6329929 100644 --- a/serde/types.nim +++ b/serde/types.nim @@ -1,6 +1,6 @@ -import ./common - type + SerdeError* = object of CatchableError + JsonParseError* = object of SerdeError UnexpectedKindError* = object of SerdeError SerdeMode* = enum OptOut, ## serialize: all object fields will be serialized, except fields marked with 'ignore' @@ -9,3 +9,6 @@ type ## deserialize: only fields marked with deserialize will be deserialized Strict ## serialize: all object fields will be serialized, regardless if the field is marked with 'ignore' ## deserialize: object fields and json fields must match exactly + SerdeFieldOptions* = object + key*: string + ignore*: bool diff --git a/tests/tests.nimble b/tests/test.nimble similarity index 71% rename from tests/tests.nimble rename to tests/test.nimble index ea43387..d76d889 100644 --- a/tests/tests.nimble +++ b/tests/test.nimble @@ -1,6 +1,6 @@ version = "0.1.0" -author = "nim-json authors" -description = "tests for nim-json library" +author = "nim json serde authors" +description = "tests for nim json serde library" license = "MIT" requires "asynctest >= 0.5.1 & < 0.6.0" diff --git a/tests/testDeserialize.nim b/tests/testDeserialize.nim index 63c575f..50d3cca 100644 --- a/tests/testDeserialize.nim +++ b/tests/testDeserialize.nim @@ -1,9 +1,7 @@ import std/math import std/options -import std/strformat import std/strutils import std/unittest -import pkg/stew/byteutils import pkg/stint import pkg/serde import pkg/questionable diff --git a/tests/testPragmas.nim b/tests/testPragmas.nim index 942744f..27180b6 100644 --- a/tests/testPragmas.nim +++ b/tests/testPragmas.nim @@ -1,14 +1,6 @@ -import std/math -import std/options -import std/strformat -import std/strutils import std/unittest import pkg/serde -import pkg/stew/byteutils -import pkg/stint -import pkg/questionable -import pkg/questionable/results suite "json serialization pragmas": diff --git a/tests/testSerializeModes.nim b/tests/testSerializeModes.nim index a2b36c2..26b8db9 100644 --- a/tests/testSerializeModes.nim +++ b/tests/testSerializeModes.nim @@ -1,6 +1,5 @@ import std/unittest -# import pkg/stint import pkg/serde suite "json serialization, mode = OptIn":