mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-02-07 05:33:51 +00:00
stackitem: split TryMake and Make
Sometimes we may need something that doesn't panic. Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
parent
673b26fdb1
commit
4da753f822
1 changed files with 44 additions and 36 deletions
|
@ -93,86 +93,94 @@ func mkInvConversion(from Item, to Type) error {
|
||||||
return fmt.Errorf("%w: %s/%s", ErrInvalidConversion, from, to)
|
return fmt.Errorf("%w: %s/%s", ErrInvalidConversion, from, to)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make tries to make an appropriate stack item from the provided value.
|
// TryMake tries to make an appropriate stack item from the provided value.
|
||||||
// It will panic if it's not possible.
|
func TryMake(v any) (Item, error) {
|
||||||
func Make(v any) Item {
|
|
||||||
switch val := v.(type) {
|
switch val := v.(type) {
|
||||||
case int:
|
case int:
|
||||||
return (*BigInteger)(big.NewInt(int64(val)))
|
return (*BigInteger)(big.NewInt(int64(val))), nil
|
||||||
case int64:
|
case int64:
|
||||||
return (*BigInteger)(big.NewInt(val))
|
return (*BigInteger)(big.NewInt(val)), nil
|
||||||
case uint8:
|
case uint8:
|
||||||
return (*BigInteger)(big.NewInt(int64(val)))
|
return (*BigInteger)(big.NewInt(int64(val))), nil
|
||||||
case uint16:
|
case uint16:
|
||||||
return (*BigInteger)(big.NewInt(int64(val)))
|
return (*BigInteger)(big.NewInt(int64(val))), nil
|
||||||
case uint32:
|
case uint32:
|
||||||
return (*BigInteger)(big.NewInt(int64(val)))
|
return (*BigInteger)(big.NewInt(int64(val))), nil
|
||||||
case uint64:
|
case uint64:
|
||||||
return (*BigInteger)(new(big.Int).SetUint64(val))
|
return (*BigInteger)(new(big.Int).SetUint64(val)), nil
|
||||||
case []byte:
|
case []byte:
|
||||||
return NewByteArray(val)
|
return NewByteArray(val), nil
|
||||||
case string:
|
case string:
|
||||||
return NewByteArray([]byte(val))
|
return NewByteArray([]byte(val)), nil
|
||||||
case bool:
|
case bool:
|
||||||
return Bool(val)
|
return Bool(val), nil
|
||||||
case []Item:
|
case []Item:
|
||||||
return &Array{
|
return &Array{
|
||||||
value: val,
|
value: val,
|
||||||
}
|
}, nil
|
||||||
case *big.Int:
|
case *big.Int:
|
||||||
return NewBigInteger(val)
|
return NewBigInteger(val), nil
|
||||||
case Item:
|
case Item:
|
||||||
return val
|
return val, nil
|
||||||
case []int:
|
case []int:
|
||||||
var res = make([]Item, len(val))
|
var res = make([]Item, len(val))
|
||||||
for i := range val {
|
for i := range val {
|
||||||
res[i] = Make(val[i])
|
res[i], _ = TryMake(val[i]) // Can't fail for int
|
||||||
}
|
}
|
||||||
return Make(res)
|
return TryMake(res)
|
||||||
case []string:
|
case []string:
|
||||||
var res = make([]Item, len(val))
|
var res = make([]Item, len(val))
|
||||||
for i := range val {
|
for i := range val {
|
||||||
res[i] = Make(val[i])
|
res[i], _ = TryMake(val[i]) // Can't fail for string
|
||||||
}
|
}
|
||||||
return Make(res)
|
return TryMake(res)
|
||||||
case []any:
|
case []any:
|
||||||
res := make([]Item, len(val))
|
res := make([]Item, len(val))
|
||||||
for i := range val {
|
for i := range val {
|
||||||
res[i] = Make(val[i])
|
var err error
|
||||||
|
|
||||||
|
res[i], err = TryMake(val[i])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return Make(res)
|
}
|
||||||
|
return TryMake(res)
|
||||||
case util.Uint160:
|
case util.Uint160:
|
||||||
return Make(val.BytesBE())
|
return TryMake(val.BytesBE())
|
||||||
case util.Uint256:
|
case util.Uint256:
|
||||||
return Make(val.BytesBE())
|
return TryMake(val.BytesBE())
|
||||||
case *util.Uint160:
|
case *util.Uint160:
|
||||||
if val == nil {
|
if val == nil {
|
||||||
return Null{}
|
return Null{}, nil
|
||||||
}
|
}
|
||||||
return Make(*val)
|
return TryMake(*val)
|
||||||
case *util.Uint256:
|
case *util.Uint256:
|
||||||
if val == nil {
|
if val == nil {
|
||||||
return Null{}
|
return Null{}, nil
|
||||||
}
|
}
|
||||||
return Make(*val)
|
return TryMake(*val)
|
||||||
case nil:
|
case nil:
|
||||||
return Null{}
|
return Null{}, nil
|
||||||
default:
|
default:
|
||||||
i64T := reflect.TypeOf(int64(0))
|
i64T := reflect.TypeOf(int64(0))
|
||||||
if reflect.TypeOf(val).ConvertibleTo(i64T) {
|
if reflect.TypeOf(val).ConvertibleTo(i64T) {
|
||||||
i64Val := reflect.ValueOf(val).Convert(i64T).Interface()
|
i64Val := reflect.ValueOf(val).Convert(i64T).Interface()
|
||||||
return Make(i64Val)
|
return TryMake(i64Val)
|
||||||
}
|
}
|
||||||
panic(
|
return nil, fmt.Errorf("%w: item %v of type %v",
|
||||||
fmt.Sprintf(
|
errors.ErrUnsupported, val, reflect.TypeOf(val))
|
||||||
"invalid stack item type: %v (%v)",
|
|
||||||
val,
|
|
||||||
reflect.TypeOf(val),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make is like TryMake, but panics if conversion isn't possible.
|
||||||
|
func Make(v any) Item {
|
||||||
|
itm, err := TryMake(v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return itm
|
||||||
|
}
|
||||||
|
|
||||||
// ToString converts an Item to a string if it is a valid UTF-8.
|
// ToString converts an Item to a string if it is a valid UTF-8.
|
||||||
func ToString(item Item) (string, error) {
|
func ToString(item Item) (string, error) {
|
||||||
bs, err := item.TryBytes()
|
bs, err := item.TryBytes()
|
||||||
|
|
Loading…
Add table
Reference in a new issue