diff options
author | Javier Peletier <jm@epiclabs.io> | 2018-03-05 23:01:40 +0800 |
---|---|---|
committer | Javier Peletier <jm@epiclabs.io> | 2018-03-05 23:01:40 +0800 |
commit | 60a999f238fca7c83b26ecf94257ee648afe4df9 (patch) | |
tree | 6416f68dcfe0b4bb6658b7a637db1a01282ca35d /accounts/abi/argument.go | |
parent | 13b566e06e9aae28bddde431c7d53a335272411a (diff) | |
download | go-tangerine-60a999f238fca7c83b26ecf94257ee648afe4df9.tar.gz go-tangerine-60a999f238fca7c83b26ecf94257ee648afe4df9.tar.zst go-tangerine-60a999f238fca7c83b26ecf94257ee648afe4df9.zip |
accounts/abi: Modified unpackAtomic to accept struct lvalues
Diffstat (limited to 'accounts/abi/argument.go')
-rw-r--r-- | accounts/abi/argument.go | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 1b480da60..512d8fdfa 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -113,16 +113,8 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa } // If the output interface is a struct, make sure names don't collide if kind == reflect.Struct { - exists := make(map[string]bool) - for _, arg := range arguments { - field := capitalise(arg.Name) - if field == "" { - return fmt.Errorf("abi: purely underscored output cannot unpack to struct") - } - if exists[field] { - return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field) - } - exists[field] = true + if err := requireUniqueStructFieldNames(arguments); err != nil { + return err } } for i, arg := range arguments.NonIndexed() { @@ -131,14 +123,9 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa switch kind { case reflect.Struct: - name := capitalise(arg.Name) - for j := 0; j < typ.NumField(); j++ { - // TODO read tags: `abi:"fieldName"` - if typ.Field(j).Name == name { - if err := set(value.Field(j), reflectValue, arg); err != nil { - return err - } - } + err := unpackStruct(value, reflectValue, arg) + if err != nil { + return err } case reflect.Slice, reflect.Array: if value.Len() < i { @@ -165,8 +152,20 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues)) } elem := reflect.ValueOf(v).Elem() + kind := elem.Kind() reflectValue := reflect.ValueOf(marshalledValues[0]) + + if kind == reflect.Struct { + //make sure names don't collide + if err := requireUniqueStructFieldNames(arguments); err != nil { + return err + } + + return unpackStruct(elem, reflectValue, arguments[0]) + } + return set(elem, reflectValue, arguments.NonIndexed()[0]) + } // Computes the full size of an array; @@ -278,3 +277,18 @@ func capitalise(input string) string { } return strings.ToUpper(input[:1]) + input[1:] } + +//unpackStruct extracts each argument into its corresponding struct field +func unpackStruct(value, reflectValue reflect.Value, arg Argument) error { + name := capitalise(arg.Name) + typ := value.Type() + for j := 0; j < typ.NumField(); j++ { + // TODO read tags: `abi:"fieldName"` + if typ.Field(j).Name == name { + if err := set(value.Field(j), reflectValue, arg); err != nil { + return err + } + } + } + return nil +} |