|
@@ -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 the output interface is a struct, make sure names don't collide
|
|
|
if kind == reflect.Struct {
|
|
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() {
|
|
for i, arg := range arguments.NonIndexed() {
|
|
@@ -131,14 +123,9 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
|
|
|
|
|
|
|
|
switch kind {
|
|
switch kind {
|
|
|
case reflect.Struct:
|
|
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:
|
|
case reflect.Slice, reflect.Array:
|
|
|
if value.Len() < i {
|
|
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))
|
|
return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues))
|
|
|
}
|
|
}
|
|
|
elem := reflect.ValueOf(v).Elem()
|
|
elem := reflect.ValueOf(v).Elem()
|
|
|
|
|
+ kind := elem.Kind()
|
|
|
reflectValue := reflect.ValueOf(marshalledValues[0])
|
|
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])
|
|
return set(elem, reflectValue, arguments.NonIndexed()[0])
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Computes the full size of an array;
|
|
// Computes the full size of an array;
|
|
@@ -278,3 +277,18 @@ func capitalise(input string) string {
|
|
|
}
|
|
}
|
|
|
return strings.ToUpper(input[:1]) + input[1:]
|
|
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
|
|
|
|
|
+}
|