nim-eth/eth/rlp/object_serialization.nim

51 lines
1.6 KiB
Nim

# eth
# Copyright (c) 2019-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
stew/shims/macros
template rlpIgnore* {.pragma.}
## Specifies that a certain field should be ignored for the purposes
## of RLP serialization
template rlpCustomSerialization* {.pragma.}
## This pragma can be applied to a record field to enable the
## use of custom `read` and `append` overloads that also take
## a reference to the object holding the field.
template enumerateRlpFields*[T](x: T, op: untyped) =
type RecordType {.used.} = type x
for fieldName, field in fieldPairs(x):
when not hasCustomPragmaFixed(RecordType, fieldName, rlpIgnore):
op(RecordType, fieldName, field)
proc rlpFieldsCount*(T: type): int =
mixin enumerateRlpFields
proc helper: int =
var dummy: T
template countFields(RT, n, x) {.used.} = inc result
enumerateRlpFields(dummy, countFields)
const res = helper()
return res
macro rlpFields*(T: typedesc, fields: varargs[untyped]): untyped =
var body = newStmtList()
let
ins = genSym(nskParam, "instance")
op = genSym(nskParam, "op")
for field in fields:
let fieldName = $field
body.add quote do: `op`(`T`, `fieldName`, `ins`.`field`)
result = quote do:
template enumerateRlpFields*(`ins`: `T`, `op`: untyped) {.inject.} =
`body`