@@ -113,16 +113,8 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
113
113
}
114
114
// If the output interface is a struct, make sure names don't collide
115
115
if kind == reflect .Struct {
116
- exists := make (map [string ]bool )
117
- for _ , arg := range arguments {
118
- field := capitalise (arg .Name )
119
- if field == "" {
120
- return fmt .Errorf ("abi: purely underscored output cannot unpack to struct" )
121
- }
122
- if exists [field ] {
123
- return fmt .Errorf ("abi: multiple outputs mapping to the same struct field '%s'" , field )
124
- }
125
- exists [field ] = true
116
+ if err := requireUniqueStructFieldNames (arguments ); err != nil {
117
+ return err
126
118
}
127
119
}
128
120
for i , arg := range arguments .NonIndexed () {
@@ -131,14 +123,9 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
131
123
132
124
switch kind {
133
125
case reflect .Struct :
134
- name := capitalise (arg .Name )
135
- for j := 0 ; j < typ .NumField (); j ++ {
136
- // TODO read tags: `abi:"fieldName"`
137
- if typ .Field (j ).Name == name {
138
- if err := set (value .Field (j ), reflectValue , arg ); err != nil {
139
- return err
140
- }
141
- }
126
+ err := unpackStruct (value , reflectValue , arg )
127
+ if err != nil {
128
+ return err
142
129
}
143
130
case reflect .Slice , reflect .Array :
144
131
if value .Len () < i {
@@ -165,8 +152,20 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf
165
152
return fmt .Errorf ("abi: wrong length, expected single value, got %d" , len (marshalledValues ))
166
153
}
167
154
elem := reflect .ValueOf (v ).Elem ()
155
+ kind := elem .Kind ()
168
156
reflectValue := reflect .ValueOf (marshalledValues [0 ])
157
+
158
+ if kind == reflect .Struct {
159
+ //make sure names don't collide
160
+ if err := requireUniqueStructFieldNames (arguments ); err != nil {
161
+ return err
162
+ }
163
+
164
+ return unpackStruct (elem , reflectValue , arguments [0 ])
165
+ }
166
+
169
167
return set (elem , reflectValue , arguments .NonIndexed ()[0 ])
168
+
170
169
}
171
170
172
171
// Computes the full size of an array;
@@ -278,3 +277,18 @@ func capitalise(input string) string {
278
277
}
279
278
return strings .ToUpper (input [:1 ]) + input [1 :]
280
279
}
280
+
281
+ //unpackStruct extracts each argument into its corresponding struct field
282
+ func unpackStruct (value , reflectValue reflect.Value , arg Argument ) error {
283
+ name := capitalise (arg .Name )
284
+ typ := value .Type ()
285
+ for j := 0 ; j < typ .NumField (); j ++ {
286
+ // TODO read tags: `abi:"fieldName"`
287
+ if typ .Field (j ).Name == name {
288
+ if err := set (value .Field (j ), reflectValue , arg ); err != nil {
289
+ return err
290
+ }
291
+ }
292
+ }
293
+ return nil
294
+ }
0 commit comments