diff --git a/compact.go b/compact.go index feef33f..9679f17 100644 --- a/compact.go +++ b/compact.go @@ -92,28 +92,24 @@ func DecodeCompact[T Numeric](buffer *bytes.Buffer) (Compact[T], error) { return Compact[T]{}, err } mode := b & 3 + var value Numeric switch mode { case 0: switch reflect.TypeOf(*new(T)) { case reflect.TypeOf(*new(U128)): - value := NewU128(big.NewInt(0).SetUint64(uint64(b >> 2))).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(big.NewInt(0).SetUint64(uint64(b >> 2)))) case reflect.TypeOf(*new(U64)): - value := NewU64(uint64(b >> 2)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU64(uint64(b >> 2))) case reflect.TypeOf(*new(U32)): - value := NewU32(uint32(b >> 2)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU32(uint32(b >> 2))) case reflect.TypeOf(*new(U16)): - value := NewU16(uint16(b >> 2)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU16(uint16(b >> 2))) case reflect.TypeOf(*new(U8)): - value := NewU8(b >> 2).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU8(b >> 2)) default: - value := NewU128(big.NewInt(0).SetUint64(uint64(b >> 2))).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(big.NewInt(0).SetUint64(uint64(b >> 2)))) } + return Compact[T]{value.(T)}, nil case 1: db, err := decoder.DecodeByte() if err != nil { @@ -124,22 +120,17 @@ func DecodeCompact[T Numeric](buffer *bytes.Buffer) (Compact[T], error) { r += uint64(b >> 2) switch reflect.TypeOf(*new(T)) { case reflect.TypeOf(*new(U128)): - value := NewU128(r).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(r)) case reflect.TypeOf(*new(U64)): - value := NewU64(r).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU64(r)) case reflect.TypeOf(*new(U32)): - value := NewU32(uint32(r)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU32(uint32(r))) case reflect.TypeOf(*new(U8)): - value := NewU8(uint8(r)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU8(uint8(r))) default: - value := NewU128(r).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(r)) } - + return Compact[T]{value.(T)}, nil case 2: buf := result[:4] buf[0] = b @@ -151,21 +142,17 @@ func DecodeCompact[T Numeric](buffer *bytes.Buffer) (Compact[T], error) { r >>= 2 switch reflect.TypeOf(*new(T)) { case reflect.TypeOf(*new(U128)): - value := NewU128(uint64(r)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(uint64(r))) case reflect.TypeOf(*new(U64)): - value := NewU64(uint64(r)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU64(uint64(r))) case reflect.TypeOf(*new(U32)): - value := NewU32(r).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU32(r)) case reflect.TypeOf(*new(U8)): - value := NewU8(uint8(r)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU8(uint8(r))) default: - value := NewU128(r).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(r)) } + return Compact[T]{value.(T)}, nil case 3: n := b >> 2 if n > 63 { @@ -180,18 +167,15 @@ func DecodeCompact[T Numeric](buffer *bytes.Buffer) (Compact[T], error) { reverseSlice(result) switch reflect.TypeOf(*new(T)) { case reflect.TypeOf(*new(U128)): - value := NewU128(big.NewInt(0).SetBytes(result)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(big.NewInt(0).SetBytes(result))) case reflect.TypeOf(*new(U64)): - value := NewU64(big.NewInt(0).SetBytes(result).Uint64()).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU64(big.NewInt(0).SetBytes(result).Uint64())) case reflect.TypeOf(*new(U32)): - value := NewU32(uint32(big.NewInt(0).SetBytes(result).Uint64())).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU32(uint32(big.NewInt(0).SetBytes(result).Uint64()))) default: - value := NewU128(big.NewInt(0).SetBytes(result)).Interface().(T) - return Compact[T]{value}, nil + value = Numeric(NewU128(big.NewInt(0).SetBytes(result))) } + return Compact[T]{value.(T)}, nil default: return Compact[T]{}, errCouldNotDecodeCompact } diff --git a/tuple.go b/tuple.go index a81ad27..a0f17ff 100644 --- a/tuple.go +++ b/tuple.go @@ -80,6 +80,12 @@ func EncodeTuple(t interface{}, buffer *bytes.Buffer) { ConvertTo[Compact[U128]](field).Encode(buffer) case reflect.TypeOf(*new(Compact[U64])): ConvertTo[Compact[U64]](field).Encode(buffer) + case reflect.TypeOf(*new(Compact[U32])): + ConvertTo[Compact[U32]](field).Encode(buffer) + case reflect.TypeOf(*new(Compact[U16])): + ConvertTo[Compact[U16]](field).Encode(buffer) + case reflect.TypeOf(*new(Compact[U8])): + ConvertTo[Compact[U8]](field).Encode(buffer) default: // Option[T], Result[T], Tuple if field.Kind() == reflect.Struct { diff --git a/tuple_test.go b/tuple_test.go index 1ba1dc6..f2fb5bb 100644 --- a/tuple_test.go +++ b/tuple_test.go @@ -216,7 +216,7 @@ type TupleCompactU128 struct { G1 Compact[U128] } -func Test_EncodeTupleCompact(t *testing.T) { +func Test_EncodeTupleCompactU128(t *testing.T) { var testExamples = []struct { label string input TupleCompactU128 @@ -246,6 +246,150 @@ func Test_EncodeTupleCompact(t *testing.T) { } } +type TupleCompactU64 struct { + Tuple + G0 Compact[U64] + G1 Compact[U64] +} + +func Test_EncodeTupleCompactU64(t *testing.T) { + var testExamples = []struct { + label string + input TupleCompactU64 + expectation []byte + }{ + { + label: "TupleCompactU64", + input: TupleCompactU64{ + G0: Compact[U64]{NewU64(1073741824)}, + G1: Compact[U64]{NewU64(1073741823)}, + }, + expectation: []byte{ + 0x03, 0x00, 0x00, 0x00, 0x40, // G0 + 0xfe, 0xff, 0xff, 0xff, // G1 + }, + }, + } + + for _, testExample := range testExamples { + t.Run(testExample.label, func(t *testing.T) { + buffer := &bytes.Buffer{} + + EncodeTuple(testExample.input, buffer) + + assert.Equal(t, testExample.expectation, buffer.Bytes()) + }) + } +} + +type TupleCompactU32 struct { + Tuple + G0 Compact[U32] + G1 Compact[U32] +} + +func Test_EncodeTupleCompactU32(t *testing.T) { + var testExamples = []struct { + label string + input TupleCompactU32 + expectation []byte + }{ + { + label: "TupleCompactU32", + input: TupleCompactU32{ + G0: Compact[U32]{NewU32(1073741824)}, + G1: Compact[U32]{NewU32(1073741823)}, + }, + expectation: []byte{ + 0x03, 0x00, 0x00, 0x00, 0x40, // G0 + 0xfe, 0xff, 0xff, 0xff, // G1 + }, + }, + } + + for _, testExample := range testExamples { + t.Run(testExample.label, func(t *testing.T) { + buffer := &bytes.Buffer{} + + EncodeTuple(testExample.input, buffer) + + assert.Equal(t, testExample.expectation, buffer.Bytes()) + }) + } +} + +type TupleCompactU16 struct { + Tuple + G0 Compact[U16] + G1 Compact[U16] +} + +func Test_EncodeTupleCompactU16(t *testing.T) { + var testExamples = []struct { + label string + input TupleCompactU16 + expectation []byte + }{ + { + label: "TupleCompactU32", + input: TupleCompactU16{ + G0: Compact[U16]{NewU16(65535)}, + G1: Compact[U16]{NewU16(16383)}, + }, + expectation: []byte{ + 0xfe, 0xff, 0x03, 0x00, // G0 + 0xfd, 0xff, // G1 + }, + }, + } + + for _, testExample := range testExamples { + t.Run(testExample.label, func(t *testing.T) { + buffer := &bytes.Buffer{} + + EncodeTuple(testExample.input, buffer) + + assert.Equal(t, testExample.expectation, buffer.Bytes()) + }) + } +} + +type TupleCompactU8 struct { + Tuple + G0 Compact[U8] + G1 Compact[U8] +} + +func Test_EncodeTupleCompactU8(t *testing.T) { + var testExamples = []struct { + label string + input TupleCompactU8 + expectation []byte + }{ + { + label: "TupleCompactU8", + input: TupleCompactU8{ + G0: Compact[U8]{NewU8(1)}, + G1: Compact[U8]{NewU8(42)}, + }, + expectation: []byte{ + 0x04, // G0 + 0xa8, // G1 + }, + }, + } + + for _, testExample := range testExamples { + t.Run(testExample.label, func(t *testing.T) { + buffer := &bytes.Buffer{} + + EncodeTuple(testExample.input, buffer) + + assert.Equal(t, testExample.expectation, buffer.Bytes()) + }) + } +} + type TupleStr struct { Tuple H0 Str diff --git a/u128.go b/u128.go index dad363b..1dc0d6a 100644 --- a/u128.go +++ b/u128.go @@ -36,10 +36,6 @@ func (n U128) Bytes() []byte { return append(n[0].Bytes(), n[1].Bytes()...) } -func (n U128) Interface() Numeric { - return n -} - func DecodeU128(buffer *bytes.Buffer) (U128, error) { decoder := Decoder{Reader: buffer} buf := make([]byte, 16) diff --git a/u128_test.go b/u128_test.go index 6b17df1..189d160 100644 --- a/u128_test.go +++ b/u128_test.go @@ -305,11 +305,6 @@ func Test_U128_ToBigInt(t *testing.T) { } } -func Test_U128_Interface(t *testing.T) { - n := NewU128(127) - assert.Equal(t, n.Interface(), Numeric(n)) -} - func Test_DecodeU128_Empty(t *testing.T) { buffer := &bytes.Buffer{} diff --git a/u16.go b/u16.go index 1d933c0..71ba0c6 100644 --- a/u16.go +++ b/u16.go @@ -28,10 +28,6 @@ func (value U16) Bytes() []byte { return result } -func (value U16) Interface() Numeric { - return value -} - func DecodeU16(buffer *bytes.Buffer) (U16, error) { decoder := Decoder{Reader: buffer} result := make([]byte, 2) diff --git a/u16_test.go b/u16_test.go index d631c67..e2ca7a6 100644 --- a/u16_test.go +++ b/u16_test.go @@ -54,11 +54,6 @@ func Test_DecodeU16(t *testing.T) { } } -func Test_U16_Interface(t *testing.T) { - n := U16(127) - assert.Equal(t, n.Interface(), Numeric(n)) -} - func Test_DecodeU16_Empty(t *testing.T) { buffer := &bytes.Buffer{} diff --git a/u32.go b/u32.go index 7d5c3b4..9c5a1fb 100644 --- a/u32.go +++ b/u32.go @@ -28,10 +28,6 @@ func (value U32) ToBigInt() *big.Int { return new(big.Int).SetUint64(uint64(value)) } -func (value U32) Interface() Numeric { - return value -} - func DecodeU32(buffer *bytes.Buffer) (U32, error) { decoder := Decoder{Reader: buffer} result := make([]byte, 4) diff --git a/u32_test.go b/u32_test.go index afaee8b..27490a8 100644 --- a/u32_test.go +++ b/u32_test.go @@ -69,8 +69,3 @@ func Test_U32_ToBigInt(t *testing.T) { assert.True(t, ok) assert.Equal(t, expect, nBigInt) } - -func Test_U32_Interface(t *testing.T) { - n := U32(127) - assert.Equal(t, n.Interface(), Numeric(n)) -} diff --git a/u64.go b/u64.go index bbd61c2..ae32b77 100644 --- a/u64.go +++ b/u64.go @@ -20,10 +20,6 @@ func (value U64) Bytes() []byte { return result } -func (value U64) Interface() Numeric { - return value -} - func NewU64(n uint64) U64 { return U64(n) } diff --git a/u64_test.go b/u64_test.go index d57e766..e0ebb50 100644 --- a/u64_test.go +++ b/u64_test.go @@ -69,8 +69,3 @@ func Test_U64_ToBigInt(t *testing.T) { assert.True(t, ok) assert.Equal(t, expect, nBigInt) } - -func Test_U64_Interface(t *testing.T) { - n := U64(127) - assert.Equal(t, n.Interface(), Numeric(n)) -} diff --git a/u8.go b/u8.go index e04a4e9..9b09e87 100644 --- a/u8.go +++ b/u8.go @@ -25,10 +25,6 @@ func (value U8) ToBigInt() *big.Int { return new(big.Int).SetUint64(uint64(value)) } -func (value U8) Interface() Numeric { - return value -} - func DecodeU8(buffer *bytes.Buffer) (U8, error) { decoder := Decoder{Reader: buffer} b, err := decoder.DecodeByte() diff --git a/u8_test.go b/u8_test.go index 77e5beb..6b8c64b 100644 --- a/u8_test.go +++ b/u8_test.go @@ -53,11 +53,6 @@ func Test_DecodeU8(t *testing.T) { } } -func Test_U8_Interface(t *testing.T) { - n := U8(127) - assert.Equal(t, n.Interface(), Numeric(n)) -} - func Test_U8_ToBigInt(t *testing.T) { n := U8(15) nBigInt := n.ToBigInt()