mirror of
https://github.com/status-im/nim-rlp.git
synced 2025-01-24 13:31:23 +00:00
Allow specifying a custom serialization procedure for a particular field
This commit is contained in:
parent
1720345a24
commit
6556821572
8
rlp.nim
8
rlp.nim
@ -3,7 +3,7 @@
|
||||
## https://ethereum.github.io/yellowpaper/paper.pdf
|
||||
|
||||
import
|
||||
strutils, parseutils,
|
||||
macros, strutils, parseutils,
|
||||
rlp/[types, writer, object_serialization],
|
||||
rlp/priv/defs
|
||||
|
||||
@ -357,7 +357,11 @@ proc readImpl(rlp: var Rlp, T: typedesc[object|tuple],
|
||||
rlp.position += payloadOffset
|
||||
|
||||
template op(field) =
|
||||
field = rlp.read(type(field))
|
||||
when hasCustomPragma(field, rlpCustomSerialization):
|
||||
field = rlp.read(type(field),
|
||||
getCustomPragmaVal(field, rlpCustomSerialization))
|
||||
else:
|
||||
field = rlp.read(type(field))
|
||||
|
||||
enumerateRlpFields(result, op)
|
||||
|
||||
|
@ -20,3 +20,9 @@ template rlpInline* {.pragma.}
|
||||
## This can be specified on a record field in order to avoid the
|
||||
## default behavior of wrapping the record in a RLP list.
|
||||
|
||||
template rlpCustomSerialization*(T: typedesc) {.pragma.}
|
||||
## This can be specified on a record field to trigger the use of a
|
||||
## custom `read` and `append` serialization functions.
|
||||
## The custom functions will be passed an additional `type` argument
|
||||
## specefied in the pragma (it is used as an overload tag)
|
||||
|
||||
|
@ -217,7 +217,12 @@ proc appendTupleOrObject(self; data: object|tuple, wrapInList: bool) =
|
||||
enumerateRlpFields(data, countFields)
|
||||
self.startList(fieldsCount)
|
||||
|
||||
template op(x) = append(self, x)
|
||||
template op(field) =
|
||||
when hasCustomPragma(field, rlpCustomSerialization):
|
||||
append(self, field, getCustomPragmaVal(field, rlpCustomSerialization))
|
||||
else:
|
||||
append(self, field)
|
||||
|
||||
enumerateRlpFields(data, op)
|
||||
|
||||
proc appendImpl(self; data: object, wrapInList = wrapObjectsInList) {.inline.} =
|
||||
|
@ -17,6 +17,11 @@ type
|
||||
b: string
|
||||
f: Foo
|
||||
|
||||
CompressedFoo = object
|
||||
|
||||
Bar2 = object
|
||||
f {.rlpCustomSerialization: CompressedFoo}: Foo
|
||||
|
||||
rlpFields Foo,
|
||||
x, y, z
|
||||
|
||||
@ -25,6 +30,14 @@ rlpFields Transaction,
|
||||
|
||||
proc default(T: typedesc): T = discard
|
||||
|
||||
proc append*(rlpWriter: var RlpWriter, f: Foo, tag: type CompressedFoo) =
|
||||
rlpWriter.append(f.x)
|
||||
rlpWriter.append(f.y.len)
|
||||
|
||||
proc read*(rlp: var Rlp, T: type Foo, tag: type CompressedFoo): Foo =
|
||||
result.x = rlp.read(uint64)
|
||||
result.y = newString(rlp.read(int))
|
||||
|
||||
test "encoding and decoding an object":
|
||||
var originalBar = Bar(b: "abracadabra",
|
||||
f: Foo(x: 5'u64, y: "hocus pocus", z: @[100, 200, 300]))
|
||||
@ -47,3 +60,13 @@ test "encoding and decoding an object":
|
||||
t2.receiver == "Bob"
|
||||
t2.amount == 1000
|
||||
|
||||
test "custom field serialization":
|
||||
var origVal = Bar2(f: Foo(x: 10'u64, y: "y", z: @[]))
|
||||
var bytes = encode(origVal)
|
||||
var r = rlpFromBytes(bytes)
|
||||
var restored = r.read(Bar2)
|
||||
|
||||
check:
|
||||
origVal.f.x == restored.f.x
|
||||
origVal.f.y.len == restored.f.y.len
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user