Skip to content

Commit

Permalink
More aliasing changes
Browse files Browse the repository at this point in the history
  • Loading branch information
cedric-cordenier committed Sep 20, 2024
1 parent 90c6855 commit 14d26c0
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 103 deletions.
9 changes: 7 additions & 2 deletions pkg/values/bytes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@ func Test_BytesUnwrapTo(t *testing.T) {

assert.Equal(t, hs, got)

var s string
err = tr.UnwrapTo(&s)
var b bool
err = tr.UnwrapTo(&b)
require.Error(t, err)

str := ""
err = tr.UnwrapTo(&str)
require.NoError(t, err)
assert.Equal(t, []byte(str), tr.Underlying)

gotB := (*[]byte)(nil)
err = tr.UnwrapTo(gotB)
assert.ErrorContains(t, err, "cannot unwrap to nil pointer")
Expand Down
113 changes: 12 additions & 101 deletions pkg/values/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ package values
import (
"errors"
"fmt"
"math"
"reflect"

"github.com/smartcontractkit/libocr/commontypes"

"github.com/smartcontractkit/chainlink-common/pkg/values/pb"
)

Expand Down Expand Up @@ -44,107 +41,21 @@ func (i *Int64) UnwrapTo(to any) error {
return fmt.Errorf("cannot unwrap to nil pointer: %+v", to)
}

switch tv := to.(type) {
case *int64:
*tv = i.Underlying
return nil
case *int32:
if i.Underlying > math.MaxInt32 {
return fmt.Errorf("cannot unwrap int64 to int32: number would overflow %d", i)
}

if i.Underlying < math.MinInt32 {
return fmt.Errorf("cannot unwrap int64 to int32: number would underflow %d", i)
}
*tv = int32(i.Underlying)
return nil
case *int:
if i.Underlying > math.MaxInt {
return fmt.Errorf("cannot unwrap int64 to int: number would overflow %d", i)
}

if i.Underlying < math.MinInt {
return fmt.Errorf("cannot unwrap int64 to int: number would underflow %d", i)
}

*tv = int(i.Underlying)
return nil
case *uint:
if i.Underlying > math.MaxInt {
return fmt.Errorf("cannot unwrap int64 to int: number would overflow %d", i)
}

if i.Underlying < 0 {
return fmt.Errorf("cannot unwrap int64 to uint: number would underflow %d", i)
}

*tv = uint(i.Underlying)
return nil
case *uint8:
if i.Underlying > math.MaxUint8 {
return fmt.Errorf("cannot unwrap int64 to uint8: number would overflow %d", i)
}

if i.Underlying < 0 {
return fmt.Errorf("cannot unwrap int64 to uint8: number would underflow %d", i)
}

*tv = uint8(i.Underlying)
return nil
case *uint32:
if i.Underlying > math.MaxInt {
return fmt.Errorf("cannot unwrap int64 to uint32: number would overflow %d", i)
}

if i.Underlying < 0 {
return fmt.Errorf("cannot unwrap int64 to uint32: number would underflow %d", i)
}

*tv = uint32(i.Underlying)
return nil
case *uint64:
if i.Underlying < 0 {
return fmt.Errorf("cannot unwrap int64 to uint: number would underflow %d", i)
}

*tv = uint64(i.Underlying)
return nil
case *commontypes.OracleID:
if i.Underlying > math.MaxUint8 {
return fmt.Errorf("cannot unwrap int64 to uint8: number would overflow %d", i)
}

if i.Underlying < 0 {
return fmt.Errorf("cannot unwrap int64 to uint8: number would underflow %d", i)
}

oi := commontypes.OracleID(uint8(i.Underlying))
*tv = oi
return nil
case *any:
*tv = i.Underlying
return nil
if reflect.ValueOf(to).Kind() != reflect.Pointer {
return fmt.Errorf("cannot unwrap to non-pointer value: %+v", to)
}

rv := reflect.ValueOf(to)
if rv.Kind() == reflect.Ptr {
switch rv.Elem().Kind() {
case reflect.Int64:
return i.UnwrapTo(rv.Convert(reflect.PointerTo(reflect.TypeOf(int64(0)))).Interface())
case reflect.Int32:
return i.UnwrapTo(rv.Convert(reflect.PointerTo(reflect.TypeOf(int32(0)))).Interface())
case reflect.Int:
return i.UnwrapTo(rv.Convert(reflect.PointerTo(reflect.TypeOf(int(0)))).Interface())
case reflect.Uint64:
return i.UnwrapTo(rv.Convert(reflect.PointerTo(reflect.TypeOf(uint64(0)))).Interface())
case reflect.Uint32:
return i.UnwrapTo(rv.Convert(reflect.PointerTo(reflect.TypeOf(uint32(0)))).Interface())
case reflect.Uint:
return i.UnwrapTo(rv.Convert(reflect.PointerTo(reflect.TypeOf(uint(0)))).Interface())
default:
// fall through to the error, default is required by lint
rToVal := reflect.Indirect(reflect.ValueOf(to))
switch rToVal.Kind() {

Check failure on line 49 in pkg/values/int.go

View workflow job for this annotation

GitHub Actions / golangci-lint

missing cases in switch of type reflect.Kind: reflect.Invalid, reflect.Bool, reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Array, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer|reflect.Ptr, reflect.Slice, reflect.String, reflect.Struct, reflect.UnsafePointer (exhaustive)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if rToVal.OverflowInt(i.Underlying) {
return fmt.Errorf("cannot unwrap int64 to %T: overflow", to)
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
if rToVal.OverflowUint(uint64(i.Underlying)) {
return fmt.Errorf("cannot unwrap int64 to %T: overflow", to)
}
}

return fmt.Errorf("cannot unwrap to type %T", to)
return unwrapTo(i.Underlying, to)
}
54 changes: 54 additions & 0 deletions pkg/values/int_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package values

import (
"math"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -36,3 +37,56 @@ func Test_IntUnwrapTo(t *testing.T) {
err = in.UnwrapTo(&i)
assert.ErrorContains(t, err, "cannot unwrap nil")
}

func Test_IntUnwrapping(t *testing.T) {
t.Run("int64 -> int32", func(st *testing.T) {
expected := int64(100)
v := NewInt64(expected)
got := int32(0)
err := v.UnwrapTo(&got)
require.NoError(t, err)
assert.Equal(t, int32(expected), got)
})

t.Run("int64 -> int32; overflow", func(st *testing.T) {
expected := int64(math.MaxInt64)
v := NewInt64(expected)
got := int32(0)
err := v.UnwrapTo(&got)
assert.NotNil(t, err)
})

t.Run("int64 -> int32; underflow", func(st *testing.T) {
expected := int64(math.MinInt64)
v := NewInt64(expected)
got := int32(0)
err := v.UnwrapTo(&got)
assert.NotNil(t, err)
})

t.Run("int64 -> uint32", func(st *testing.T) {
expected := int64(100)
v := NewInt64(expected)
got := uint32(0)
err := v.UnwrapTo(&got)
require.NoError(t, err)
assert.Equal(t, uint32(expected), got)
})

t.Run("int64 -> uint32; overflow", func(st *testing.T) {
expected := int64(math.MaxInt64)
v := NewInt64(expected)
got := uint32(0)
err := v.UnwrapTo(&got)
assert.NotNil(t, err)
})

t.Run("int64 -> int32; underflow", func(st *testing.T) {
expected := int64(math.MinInt64)
v := NewInt64(expected)
got := uint32(0)
err := v.UnwrapTo(&got)
assert.NotNil(t, err)
})

}

Check failure on line 92 in pkg/values/int_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unnecessary trailing newline (whitespace)
6 changes: 6 additions & 0 deletions pkg/values/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,12 @@ func unwrapTo[T any](underlying T, to any) error {
return nil
}

if rUnderlying.CanConvert(reflect.Indirect(rTo).Type()) {
conv := rUnderlying.Convert(reflect.Indirect(rTo).Type())
reflect.Indirect(rTo).Set(conv)
return nil
}

rToVal := reflect.Indirect(rTo)
if rUnderlying.Kind() == reflect.Slice {
var newList reflect.Value
Expand Down

0 comments on commit 14d26c0

Please sign in to comment.