@@ -18,6 +18,7 @@ import (
18
18
)
19
19
20
20
const (
21
+ comma = ","
21
22
defaultKeyName = "key"
22
23
delimiter = '.'
23
24
ignoreKey = "-"
36
37
defaultCacheLock sync.Mutex
37
38
emptyMap = map [string ]any {}
38
39
emptyValue = reflect .ValueOf (lang .Placeholder )
40
+ stringSliceType = reflect .TypeOf ([]string {})
39
41
)
40
42
41
43
type (
@@ -173,13 +175,18 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value,
173
175
baseType := fieldType .Elem ()
174
176
dereffedBaseType := Deref (baseType )
175
177
dereffedBaseKind := dereffedBaseType .Kind ()
176
- conv := reflect .MakeSlice (reflect .SliceOf (baseType ), refValue .Len (), refValue .Cap ())
177
178
if refValue .Len () == 0 {
178
- value .Set (conv )
179
+ value .Set (reflect . MakeSlice ( reflect . SliceOf ( baseType ), 0 , 0 ) )
179
180
return nil
180
181
}
181
182
183
+ if u .opts .fromArray {
184
+ refValue = makeStringSlice (refValue )
185
+ }
186
+
182
187
var valid bool
188
+ conv := reflect .MakeSlice (reflect .SliceOf (baseType ), refValue .Len (), refValue .Cap ())
189
+
183
190
for i := 0 ; i < refValue .Len (); i ++ {
184
191
ithValue := refValue .Index (i ).Interface ()
185
192
if ithValue == nil {
@@ -191,17 +198,9 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value,
191
198
192
199
switch dereffedBaseKind {
193
200
case reflect .Struct :
194
- target := reflect .New (dereffedBaseType )
195
- val , ok := ithValue .(map [string ]any )
196
- if ! ok {
197
- return errTypeMismatch
198
- }
199
-
200
- if err := u .unmarshal (val , target .Interface (), sliceFullName ); err != nil {
201
+ if err := u .fillStructElement (baseType , conv .Index (i ), ithValue , sliceFullName ); err != nil {
201
202
return err
202
203
}
203
-
204
- SetValue (fieldType .Elem (), conv .Index (i ), target .Elem ())
205
204
case reflect .Slice :
206
205
if err := u .fillSlice (dereffedBaseType , conv .Index (i ), ithValue , sliceFullName ); err != nil {
207
206
return err
@@ -310,6 +309,23 @@ func (u *Unmarshaler) fillSliceWithDefault(derefedType reflect.Type, value refle
310
309
return u .fillSlice (derefedType , value , slice , fullName )
311
310
}
312
311
312
+ func (u * Unmarshaler ) fillStructElement (baseType reflect.Type , target reflect.Value ,
313
+ value any , fullName string ) error {
314
+ val , ok := value .(map [string ]any )
315
+ if ! ok {
316
+ return errTypeMismatch
317
+ }
318
+
319
+ // use Deref(baseType) to get the base type in case the type is a pointer type.
320
+ ptr := reflect .New (Deref (baseType ))
321
+ if err := u .unmarshal (val , ptr .Interface (), fullName ); err != nil {
322
+ return err
323
+ }
324
+
325
+ SetValue (baseType , target , ptr .Elem ())
326
+ return nil
327
+ }
328
+
313
329
func (u * Unmarshaler ) fillUnmarshalerStruct (fieldType reflect.Type ,
314
330
value reflect.Value , targetValue string ) error {
315
331
if ! value .CanSet () {
@@ -1146,6 +1162,34 @@ func join(elem ...string) string {
1146
1162
return builder .String ()
1147
1163
}
1148
1164
1165
+ func makeStringSlice (refValue reflect.Value ) reflect.Value {
1166
+ if refValue .Len () != 1 {
1167
+ return refValue
1168
+ }
1169
+
1170
+ element := refValue .Index (0 )
1171
+ if element .Kind () != reflect .String {
1172
+ return refValue
1173
+ }
1174
+
1175
+ val , ok := element .Interface ().(string )
1176
+ if ! ok {
1177
+ return refValue
1178
+ }
1179
+
1180
+ splits := strings .Split (val , comma )
1181
+ if len (splits ) <= 1 {
1182
+ return refValue
1183
+ }
1184
+
1185
+ slice := reflect .MakeSlice (stringSliceType , len (splits ), len (splits ))
1186
+ for i , split := range splits {
1187
+ slice .Index (i ).Set (reflect .ValueOf (split ))
1188
+ }
1189
+
1190
+ return slice
1191
+ }
1192
+
1149
1193
func newInitError (name string ) error {
1150
1194
return fmt .Errorf ("field %q is not set" , name )
1151
1195
}
0 commit comments