Add rlpFieldsCount helper and the ability to read objects not wrapped in lists

This commit is contained in:
Zahary Karadjov 2018-10-16 02:09:11 +03:00
parent 2b28b1a236
commit 1be7c93963
4 changed files with 28 additions and 13 deletions

View File

@ -354,7 +354,7 @@ proc readImpl[E](rlp: var Rlp, T: type openarray[E]): seq[E] =
result = readImpl(rlp, seq[E])
proc readImpl(rlp: var Rlp, T: type[object|tuple],
wrappedInList = wrapObjectsInList): T =
wrappedInList = wrapObjsInList): T =
mixin enumerateRlpFields, read
if wrappedInList:
@ -391,6 +391,9 @@ proc toNodes*(self: var Rlp): RlpNode =
template read*(rlp: var Rlp, T: type): auto =
readImpl(rlp, T)
template readRecordType*(rlp: var Rlp, T: type, wrappedInList: bool): auto =
readImpl(rlp, T, wrappedInList)
proc decode*(bytes: openarray[byte]): RlpNode =
var
bytesCopy = @bytes

View File

@ -18,6 +18,17 @@ template enumerateRlpFields*[T](x: T, op: untyped) =
when not hasCustomPragma(f, rlpIgnore):
op(f)
proc rlpFieldsCount*(T: type): int =
mixin enumerateRlpFields
proc helper: int =
var dummy: T
template countFields(x) = inc result
enumerateRlpFields(dummy, countFields)
const res = helper()
return res
macro rlpFields*(T: typedesc, fields: varargs[untyped]): untyped =
var body = newStmtList()
let

View File

@ -32,7 +32,7 @@ type
Integer* = SomeInteger # or IntLike
const
wrapObjectsInList* = true
wrapObjsInList* = true
proc bytesNeeded(num: Integer): int =
type IntType = type(num)
@ -214,16 +214,11 @@ proc appendImpl[T](self; listOrBlob: openarray[T]) =
for i in 0 ..< listOrBlob.len:
self.append listOrBlob[i]
proc appendTupleOrObject(self; obj: object|tuple, wrapInList: bool) =
proc appendRecordType*(self; obj: object|tuple, wrapInList = wrapObjsInList) =
mixin enumerateRlpFields, append
const wrapInList = wrapObjectsInList
if wrapInList:
var fieldsCount = 0
template countFields(x) = inc fieldsCount
enumerateRlpFields(obj, countFields)
self.startList(fieldsCount)
self.startList(static obj.type.rlpFieldsCount)
template op(field) =
when hasCustomPragma(field, rlpCustomSerialization):
@ -233,16 +228,16 @@ proc appendTupleOrObject(self; obj: object|tuple, wrapInList: bool) =
enumerateRlpFields(obj, op)
proc appendImpl(self; data: object, wrapInList = wrapObjectsInList) {.inline.} =
proc appendImpl(self; data: object) {.inline.} =
# TODO: This append proc should be overloaded by `BytesRange` after
# nim bug #7416 is fixed.
when data is BytesRange:
self.appendBytesRange(data)
else:
self.appendTupleOrObject(data, wrapInList)
self.appendRecordType(data)
proc appendImpl(self; data: tuple, wrapInList = wrapObjectsInList) {.inline.} =
self.appendTupleOrObject(data, wrapInList)
proc appendImpl(self; data: tuple) {.inline.} =
self.appendRecordType(data)
# We define a single `append` template with a pretty low specifity
# score in order to facilitate easier overloading with user types:

View File

@ -74,3 +74,9 @@ test "custom field serialization":
origVal.customFoo.y.len == restored.customFoo.y.len
restored.ignored == 10
test "RLP fields count":
check:
Bar.rlpFieldsCount == 2
Foo.rlpFieldsCount == 3
Transaction.rlpFieldsCount == 3