unwrap: add a complete set of simple array unwrappers
Arrays of basic types should be covered completely.
This commit is contained in:
parent
f78231fd9c
commit
b5c79f4be3
2 changed files with 153 additions and 0 deletions
|
@ -196,6 +196,42 @@ func Array(r *result.Invoke, err error) ([]stackitem.Item, error) {
|
||||||
return arr, nil
|
return arr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ArrayOfBools checks the result for correct state (HALT) and then extracts a
|
||||||
|
// slice of boolean values from the returned stack item.
|
||||||
|
func ArrayOfBools(r *result.Invoke, err error) ([]bool, error) {
|
||||||
|
a, err := Array(r, err)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res := make([]bool, len(a))
|
||||||
|
for i := range a {
|
||||||
|
b, err := a[i].TryBool()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("element %d is not a boolean: %w", i, err)
|
||||||
|
}
|
||||||
|
res[i] = b
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArrayOfBigInts checks the result for correct state (HALT) and then extracts a
|
||||||
|
// slice of (big) integer values from the returned stack item.
|
||||||
|
func ArrayOfBigInts(r *result.Invoke, err error) ([]*big.Int, error) {
|
||||||
|
a, err := Array(r, err)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res := make([]*big.Int, len(a))
|
||||||
|
for i := range a {
|
||||||
|
v, err := a[i].TryInteger()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("element %d is not an integer: %w", i, err)
|
||||||
|
}
|
||||||
|
res[i] = v
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ArrayOfBytes checks the result for correct state (HALT) and then extracts a
|
// ArrayOfBytes checks the result for correct state (HALT) and then extracts a
|
||||||
// slice of byte slices from the returned stack item.
|
// slice of byte slices from the returned stack item.
|
||||||
func ArrayOfBytes(r *result.Invoke, err error) ([][]byte, error) {
|
func ArrayOfBytes(r *result.Invoke, err error) ([][]byte, error) {
|
||||||
|
@ -214,6 +250,27 @@ func ArrayOfBytes(r *result.Invoke, err error) ([][]byte, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ArrayOfUTB8Strings checks the result for correct state (HALT) and then extracts a
|
||||||
|
// slice of UTF-8 strings from the returned stack item.
|
||||||
|
func ArrayOfUTF8Strings(r *result.Invoke, err error) ([]string, error) {
|
||||||
|
a, err := Array(r, err)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res := make([]string, len(a))
|
||||||
|
for i := range a {
|
||||||
|
b, err := a[i].TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("element %d is not a byte string: %w", i, err)
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return nil, fmt.Errorf("element %d is not a UTF-8 string", i)
|
||||||
|
}
|
||||||
|
res[i] = string(b)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ArrayOfUint160 checks the result for correct state (HALT) and then extracts a
|
// ArrayOfUint160 checks the result for correct state (HALT) and then extracts a
|
||||||
// slice of util.Uint160 from the returned stack item.
|
// slice of util.Uint160 from the returned stack item.
|
||||||
func ArrayOfUint160(r *result.Invoke, err error) ([]util.Uint160, error) {
|
func ArrayOfUint160(r *result.Invoke, err error) ([]util.Uint160, error) {
|
||||||
|
@ -236,6 +293,28 @@ func ArrayOfUint160(r *result.Invoke, err error) ([]util.Uint160, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ArrayOfUint256 checks the result for correct state (HALT) and then extracts a
|
||||||
|
// slice of util.Uint256 from the returned stack item.
|
||||||
|
func ArrayOfUint256(r *result.Invoke, err error) ([]util.Uint256, error) {
|
||||||
|
a, err := Array(r, err)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res := make([]util.Uint256, len(a))
|
||||||
|
for i := range a {
|
||||||
|
b, err := a[i].TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("element %d is not a byte string: %w", i, err)
|
||||||
|
}
|
||||||
|
u, err := util.Uint256DecodeBytesBE(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("element %d is not a uint256: %w", i, err)
|
||||||
|
}
|
||||||
|
res[i] = u
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ArrayOfPublicKeys checks the result for correct state (HALT) and then
|
// ArrayOfPublicKeys checks the result for correct state (HALT) and then
|
||||||
// extracts a slice of public keys from the returned stack item.
|
// extracts a slice of public keys from the returned stack item.
|
||||||
func ArrayOfPublicKeys(r *result.Invoke, err error) (keys.PublicKeys, error) {
|
func ArrayOfPublicKeys(r *result.Invoke, err error) (keys.PublicKeys, error) {
|
||||||
|
|
|
@ -53,9 +53,24 @@ func TestStdErrors(t *testing.T) {
|
||||||
func(r *result.Invoke, err error) (interface{}, error) {
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
return Array(r, err)
|
return Array(r, err)
|
||||||
},
|
},
|
||||||
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
|
return ArrayOfBools(r, err)
|
||||||
|
},
|
||||||
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
|
return ArrayOfBigInts(r, err)
|
||||||
|
},
|
||||||
func(r *result.Invoke, err error) (interface{}, error) {
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
return ArrayOfBytes(r, err)
|
return ArrayOfBytes(r, err)
|
||||||
},
|
},
|
||||||
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
|
return ArrayOfUTF8Strings(r, err)
|
||||||
|
},
|
||||||
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
|
return ArrayOfUint160(r, err)
|
||||||
|
},
|
||||||
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
|
return ArrayOfUint256(r, err)
|
||||||
|
},
|
||||||
func(r *result.Invoke, err error) (interface{}, error) {
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
return ArrayOfPublicKeys(r, err)
|
return ArrayOfPublicKeys(r, err)
|
||||||
},
|
},
|
||||||
|
@ -233,6 +248,32 @@ func TestArray(t *testing.T) {
|
||||||
require.Equal(t, stackitem.Make(42), a[0])
|
require.Equal(t, stackitem.Make(42), a[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArrayOfBools(t *testing.T) {
|
||||||
|
_, err := ArrayOfBools(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfBools(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make("reallybigstringthatcantbeanumberandthuscantbeconvertedtobool")})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
a, err := ArrayOfBools(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make(true)})}}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(a))
|
||||||
|
require.Equal(t, true, a[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestArrayOfBigInts(t *testing.T) {
|
||||||
|
_, err := ArrayOfBigInts(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfBigInts(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]stackitem.Item{})})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
a, err := ArrayOfBigInts(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make(42)})}}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(a))
|
||||||
|
require.Equal(t, big.NewInt(42), a[0])
|
||||||
|
}
|
||||||
|
|
||||||
func TestArrayOfBytes(t *testing.T) {
|
func TestArrayOfBytes(t *testing.T) {
|
||||||
_, err := ArrayOfBytes(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
_, err := ArrayOfBytes(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
@ -246,6 +287,22 @@ func TestArrayOfBytes(t *testing.T) {
|
||||||
require.Equal(t, []byte("some"), a[0])
|
require.Equal(t, []byte("some"), a[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArrayOfUTF8Strings(t *testing.T) {
|
||||||
|
_, err := ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]stackitem.Item{})})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]byte{0, 0xff})})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
a, err := ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make("some")})}}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(a))
|
||||||
|
require.Equal(t, "some", a[0])
|
||||||
|
}
|
||||||
|
|
||||||
func TestArrayOfUint160(t *testing.T) {
|
func TestArrayOfUint160(t *testing.T) {
|
||||||
_, err := ArrayOfUint160(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
_, err := ArrayOfUint160(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
@ -263,6 +320,23 @@ func TestArrayOfUint160(t *testing.T) {
|
||||||
require.Equal(t, u160, uints[0])
|
require.Equal(t, u160, uints[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArrayOfUint256(t *testing.T) {
|
||||||
|
_, err := ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]stackitem.Item{})})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]byte("some"))})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
u256 := util.Uint256{1, 2, 3}
|
||||||
|
uints, err := ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make(u256.BytesBE())})}}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(uints))
|
||||||
|
require.Equal(t, u256, uints[0])
|
||||||
|
}
|
||||||
|
|
||||||
func TestArrayOfPublicKeys(t *testing.T) {
|
func TestArrayOfPublicKeys(t *testing.T) {
|
||||||
_, err := ArrayOfPublicKeys(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
_, err := ArrayOfPublicKeys(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
Loading…
Reference in a new issue