Skip to content

Commit

Permalink
DecodeCompact: cast to Numeric; remove Interface
Browse files Browse the repository at this point in the history
  • Loading branch information
nicksinch committed Dec 22, 2023
1 parent c4c9b60 commit 9898148
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 87 deletions.
66 changes: 25 additions & 41 deletions compact.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)))

Check warning on line 104 in compact.go

View check run for this annotation

Codecov / codecov/patch

compact.go#L99-L104

Added lines #L99 - L104 were not covered by tests
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 {
Expand All @@ -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)))

Check warning on line 129 in compact.go

View check run for this annotation

Codecov / codecov/patch

compact.go#L122-L129

Added lines #L122 - L129 were not covered by tests
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
Expand All @@ -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)))

Check warning on line 151 in compact.go

View check run for this annotation

Codecov / codecov/patch

compact.go#L144-L151

Added lines #L144 - L151 were not covered by tests
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 {
Expand All @@ -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

Check warning on line 180 in compact.go

View check run for this annotation

Codecov / codecov/patch

compact.go#L180

Added line #L180 was not covered by tests
}
Expand Down
6 changes: 6 additions & 0 deletions tuple.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
146 changes: 145 additions & 1 deletion tuple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions u128.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 0 additions & 5 deletions u128_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}

Expand Down
4 changes: 0 additions & 4 deletions u16.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 0 additions & 5 deletions u16_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}

Expand Down
4 changes: 0 additions & 4 deletions u32.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 0 additions & 5 deletions u32_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
4 changes: 0 additions & 4 deletions u64.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
5 changes: 0 additions & 5 deletions u64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
4 changes: 0 additions & 4 deletions u8.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
5 changes: 0 additions & 5 deletions u8_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 9898148

Please sign in to comment.