From f80f453933f5b9b985ec28236932972b472cb4c3 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 11 Sep 2024 16:20:08 +0300 Subject: [PATCH] smartcontract: use generics to simplify slice handling It's all the same in its essence. Signed-off-by: Roman Khimov --- pkg/smartcontract/parameter.go | 45 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/pkg/smartcontract/parameter.go b/pkg/smartcontract/parameter.go index 0b1bb96ab9..3bb88b0709 100644 --- a/pkg/smartcontract/parameter.go +++ b/pkg/smartcontract/parameter.go @@ -343,35 +343,16 @@ func NewParameterFromValue(value any) (Parameter, error) { result.Type = PublicKeyType result.Value = v.Bytes() case [][]byte: - arr := make([]Parameter, 0, len(v)) - for i := range v { - // We know the type exactly, so error is not possible. - elem, _ := NewParameterFromValue(v[i]) - arr = append(arr, elem) - } - result.Type = ArrayType - result.Value = arr + return newArrayParameter(v) case []Parameter: result.Type = ArrayType result.Value = slices.Clone(v) case []*keys.PublicKey: - return NewParameterFromValue(keys.PublicKeys(v)) + return newArrayParameter(v) case keys.PublicKeys: - arr := make([]Parameter, 0, len(v)) - for i := range v { - // We know the type exactly, so error is not possible. - elem, _ := NewParameterFromValue(v[i]) - arr = append(arr, elem) - } - result.Type = ArrayType - result.Value = arr + return newArrayParameter(v) case []any: - arr, err := NewParametersFromValues(v...) - if err != nil { - return result, err - } - result.Type = ArrayType - result.Value = arr + return newArrayParameter(v) case nil: result.Type = AnyType default: @@ -381,9 +362,15 @@ func NewParameterFromValue(value any) (Parameter, error) { return result, nil } -// NewParametersFromValues is similar to NewParameterFromValue except that it -// works with multiple values and returns a simple slice of Parameter. -func NewParametersFromValues(values ...any) ([]Parameter, error) { +func newArrayParameter[E any, S ~[]E](values S) (Parameter, error) { + arr, err := newArrayOfParameters(values) + if err != nil { + return Parameter{}, err + } + return Parameter{Type: ArrayType, Value: arr}, nil +} + +func newArrayOfParameters[E any, S ~[]E](values S) ([]Parameter, error) { res := make([]Parameter, 0, len(values)) for i := range values { elem, err := NewParameterFromValue(values[i]) @@ -395,6 +382,12 @@ func NewParametersFromValues(values ...any) ([]Parameter, error) { return res, nil } +// NewParametersFromValues is similar to NewParameterFromValue except that it +// works with multiple values and returns a simple slice of Parameter. +func NewParametersFromValues(values ...any) ([]Parameter, error) { + return newArrayOfParameters(values) +} + // ExpandParameterToEmitable converts a parameter to a type which can be handled as // an array item by emit.Array. It correlates with the way an RPC server handles // FuncParams for invoke* calls inside the request.ExpandArrayIntoScript function.