diff --git a/Readme.md b/Readme.md index 933308d..8c5fa6a 100644 --- a/Readme.md +++ b/Readme.md @@ -19,12 +19,12 @@ Usage ```nim import contractabi -import stint # encode unsigned integers, booleans, enums AbiEncoder.encode(42'u8) # encode uint256 +import stint AbiEncoder.encode(42.u256) # encode byte arrays and sequences @@ -42,6 +42,21 @@ AbiDecoder.decode(bytes, seq[uint8]) # decode tuples AbiDecoder.decode(bytes, (uint32, bool, seq[byte]) ) + +# add support for encoding of custom types +import questionable/results + +type CustomType = object + a: uint16 + b: string + +func encode(encoder: var AbiEncoder, custom: CustomType) = + encoder.write( (custom.a, custom.b) ) + +func decode(decoder: var AbiDecoder, T: type CustomType): ?!T = + let (a, b) = ?decoder.read( (uint16, string) ) + success CustomType(a: a, b: b) + ``` [1]: https://docs.soliditylang.org/en/latest/abi-spec.html diff --git a/contractabi/decoding.nim b/contractabi/decoding.nim index e4a6651..18c5697 100644 --- a/contractabi/decoding.nim +++ b/contractabi/decoding.nim @@ -146,9 +146,6 @@ func decode[T: tuple](decoder: var AbiDecoder, _: typedesc[T]): ?!T = decoder.finishTuple() success tupl -func read*(decoder: var AbiDecoder, T: type): ?!T = - decoder.decode(T) - func finish(decoder: var AbiDecoder): ?!void = doAssert decoder.stack.len == 1, "not all tuples were finished" doAssert decoder.last mod 32 == 0, "encoding invariant broken" @@ -183,3 +180,6 @@ func decode*(_: type AbiDecoder, bytes: seq[byte], T: type): ?!T = var value = ?decoder.decode(T) ?decoder.finish() success value + +func read*(decoder: var AbiDecoder, T: type): ?!T = + decoder.decode(T) diff --git a/tests/contractabi/testCustomTypes.nim b/tests/contractabi/testCustomTypes.nim new file mode 100644 index 0000000..9966da6 --- /dev/null +++ b/tests/contractabi/testCustomTypes.nim @@ -0,0 +1,25 @@ +import std/unittest +import pkg/questionable/results +import contractabi + +type CustomType = object + a: uint16 + b: string + +func encode(encoder: var AbiEncoder, custom: CustomType) = + encoder.write( (custom.a, custom.b) ) + +func decode(decoder: var AbiDecoder, T: type CustomType): ?!T = + let (a, b) = ?decoder.read( (uint16, string) ) + success CustomType(a: a, b: b) + +suite "custom types": + + let custom = CustomType(a: 42, b: "ultimate answer") + + test "can be encoded": + check AbiEncoder.encode(custom) == AbiEncoder.encode( (custom.a, custom.b) ) + + test "can be decoded": + let encoding = AbiEncoder.encode(custom) + check AbiDecoder.decode(encoding, CustomType) == success custom diff --git a/tests/testAll.nim b/tests/testAll.nim index f8eecc9..c3c66a0 100644 --- a/tests/testAll.nim +++ b/tests/testAll.nim @@ -1,4 +1,5 @@ import ./contractabi/testEncoding import ./contractabi/testDecoding +import ./contractabi/testCustomTypes {.warning[UnusedImport]:off.}