diff --git a/serialization/object_serialization.nim b/serialization/object_serialization.nim index 2e6ebe7..e6ecc4c 100644 --- a/serialization/object_serialization.nim +++ b/serialization/object_serialization.nim @@ -101,6 +101,7 @@ macro enumAllSerializedFieldsImpl(T: type, body: untyped): untyped = let fieldType = field.typ + FieldTypeSym = getTypeInst(fieldType) fieldIdent = field.name realFieldName = newLit($fieldIdent.skipPragma) serializedFieldName = field.readPragma("serializedFieldName") @@ -132,14 +133,15 @@ macro enumAllSerializedFieldsImpl(T: type, body: untyped): untyped = result.add quote do: block: when compiles(type(`field`)): - `fieldNameDefs` - type FieldType {.inject, used.} = type(`field`) - template fieldCaseDiscriminator: auto {.used.} = `discriminator` - template fieldCaseBranches: auto {.used.} = `branches` + when FieldType is `FieldTypeSym`: + `fieldNameDefs` - `body` + template fieldCaseDiscriminator: auto {.used.} = `discriminator` + template fieldCaseBranches: auto {.used.} = `branches` + + `body` i += 1 diff --git a/tests/test_object_serialization.nim b/tests/test_object_serialization.nim index 1ca35cd..c0a2586 100644 --- a/tests/test_object_serialization.nim +++ b/tests/test_object_serialization.nim @@ -4,19 +4,41 @@ import ../serialization/object_serialization, ../serialization/testing/generic_suite +type + Untrusted = object + Trusted = object + + Signature = object + p: int + k: float + + TrustedSignature = object + data: string + + SignatureHolder[TrustLevel] = object + when TrustLevel is Trusted: + sig: TrustedSignature + origin: string + else: + sig: Signature + +func collectFields(T: type): seq[string] = + enumAllSerializedFields(T): + result.add(name(FieldType) & " " & fieldName & fieldCaseDiscriminator) + suite "object serialization": - setup: - var fieldsList = newSeq[string]() - test "custom fields order": - enumAllSerializedFields(Simple): - fieldsList.add(name(FieldType) & " " & fieldName & fieldCaseDiscriminator) - - check fieldsList == @["Meter distance", "int x", "string y"] + check collectFields(Simple) == @["Meter distance", "int x", "string y"] test "tuples handling": + var fieldsList = newSeq[string]() + enumAllSerializedFields(HoldsTuples): fieldsList.add(fieldName & ": " & $isTuple(FieldType)) check fieldsList == @["t1: true", "t2: true", "t3: true"] + test "when statements": + check collectFields(SignatureHolder[Trusted]) == @["TrustedSignature sig", "string origin"] + check collectFields(SignatureHolder[Untrusted]) == @["Signature sig"] +