mirror of https://github.com/status-im/nim-rlp.git
Add rlpFieldsCount helper and the ability to read objects not wrapped in lists
This commit is contained in:
parent
2b28b1a236
commit
1be7c93963
5
rlp.nim
5
rlp.nim
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue