Initial simple/naive implementation of the field enumeration logic

This commit is contained in:
Zahary Karadjov 2018-11-11 13:40:19 +02:00
parent cd744a5450
commit c8c8e3b7e2
3 changed files with 58 additions and 14 deletions

View File

@ -1,5 +1,8 @@
import streams
export streams
import
serialization/[streams, object_serialization]
export
streams, object_serialization
proc encode*(Writer: type, value: auto): auto =
# TODO: define a concept for the Writer types

View File

@ -3,19 +3,8 @@ mode = ScriptMode.Verbose
packageName = "serialization"
version = "0.1.0"
author = "Status Research & Development GmbH"
description = "A modern extensible serialization framework for Nim"
description = "A modern and extensible serialization framework for Nim"
license = "Apache License 2.0"
skipDirs = @["tests"]
requires "nim >= 0.19.0"
proc configForTests() =
--hints: off
--debuginfo
--path: "."
--run
task test, "run tests":
configForTests()
setCommand "c", "tests/all.nim"

View File

@ -0,0 +1,52 @@
import macros
template dontSerialize* {.pragma.}
## Specifies that a certain field should be ignored for
## the purposes of serialization
template customSerialization* {.pragma.}
## This pragma can be applied to a record field to enable the
## use of custom `readValue` overloads that also take a reference
## to the object holding the field.
##
## TODO: deprecate this in favor of readField(T, field, InputArchive)
template eachSerializedFieldImpl*[T](x: T, op: untyped) =
for k, v in fieldPairs(x):
when not hasCustomPragma(v, dontSerialize):
op(k, v)
proc totalSerializedFieldsImpl(T: type): int =
mixin eachSerializedFieldImpl
proc helper: int =
var dummy: T
template countFields(x) = inc result
eachSerializedFieldImpl(dummy, countFields)
const res = helper()
return res
template totalSerializedFields*(T: type): int =
(static(totalSerializedFieldsImpl(T)))
macro serialziedFields*(T: typedesc, fields: varargs[untyped]): untyped =
var body = newStmtList()
let
ins = genSym(nskParam, "instance")
op = genSym(nskParam, "op")
for field in fields:
body.add quote do: `op`(`ins`.`field`)
result = quote do:
template eachSerializedFieldImpl*(`ins`: `T`, `op`: untyped) {.inject.} =
`body`
template serializeFields*(value: auto, fieldName, fieldValue, body: untyped) =
# TODO: this would be nicer as a for loop macro
mixin eachSerializedFieldImpl
template op(fieldName, fieldValue: untyped) = body
eachSerializedFieldImpl(value, op)