@@ -52,18 +52,24 @@ type (
52
52
UnmarshalOption func (* unmarshalOptions )
53
53
54
54
unmarshalOptions struct {
55
- fillDefault bool
56
- fromArray bool
57
- fromString bool
58
- opaqueKeys bool
59
- canonicalKey func (key string ) string
55
+ fillDefault bool
56
+ fromArray bool
57
+ fromString bool
58
+ opaqueKeys bool
59
+ canonicalKey func (key string ) string
60
+ formCommaArray bool //a new Switch to control the form comma-split array parse,default is true
60
61
}
61
62
)
62
63
63
64
// NewUnmarshaler returns an Unmarshaler.
64
65
func NewUnmarshaler (key string , opts ... UnmarshalOption ) * Unmarshaler {
65
66
unmarshaler := Unmarshaler {
66
67
key : key ,
68
+ opts : unmarshalOptions {
69
+ // The comma split form array mode was enabled in 1.7.5
70
+ // so the default value is true in order not to introduce destructiveness
71
+ formCommaArray : true ,
72
+ },
67
73
}
68
74
69
75
for _ , opt := range opts {
@@ -152,6 +158,7 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value,
152
158
return nil
153
159
}
154
160
161
+ refValue = makeStringSlice (dereffedBaseKind , refValue , u .opts )
155
162
var valid bool
156
163
conv := reflect .MakeSlice (reflect .SliceOf (baseType ), refValue .Len (), refValue .Cap ())
157
164
@@ -1053,6 +1060,21 @@ func WithFromArray() UnmarshalOption {
1053
1060
}
1054
1061
}
1055
1062
1063
+ // WithFormCommaArray b is a switch to enable comma-split array values.
1064
+ // if b == false will be disable form param comma-split format array values
1065
+ // else will be enable above
1066
+ //
1067
+ // For example, if the field type is []string,
1068
+ // GET /a?code=1,2,3,4,5
1069
+ //
1070
+ // if b==false will be code=[]string{"1,2,3,4,5"}
1071
+ // else will be code=[]string{"1","2","3","4","5"}
1072
+ func WithFormCommaArray (b bool ) UnmarshalOption {
1073
+ return func (opt * unmarshalOptions ) {
1074
+ opt .formCommaArray = b
1075
+ }
1076
+ }
1077
+
1056
1078
// WithOpaqueKeys customizes an Unmarshaler with opaque keys.
1057
1079
// Opaque keys are keys that are not processed by the unmarshaler.
1058
1080
func WithOpaqueKeys () UnmarshalOption {
@@ -1185,6 +1207,40 @@ func join(elem ...string) string {
1185
1207
return builder .String ()
1186
1208
}
1187
1209
1210
+ func makeStringSlice (dereffedBaseKind reflect.Kind , refValue reflect.Value , opts unmarshalOptions ) reflect.Value {
1211
+ if ! opts .fromArray {
1212
+ return refValue
1213
+ }
1214
+ if refValue .Len () != 1 {
1215
+ return refValue
1216
+ }
1217
+
1218
+ element := refValue .Index (0 )
1219
+ if element .Kind () != reflect .String {
1220
+ return refValue
1221
+ }
1222
+
1223
+ val , ok := element .Interface ().(string )
1224
+ if ! ok {
1225
+ return refValue
1226
+ }
1227
+ if dereffedBaseKind != reflect .String || opts .formCommaArray {
1228
+ splits := strings .Split (val , comma )
1229
+ if len (splits ) <= 1 {
1230
+ return refValue
1231
+ }
1232
+
1233
+ slice := reflect .MakeSlice (stringSliceType , len (splits ), len (splits ))
1234
+ for i , split := range splits {
1235
+ // allow empty strings
1236
+ slice .Index (i ).Set (reflect .ValueOf (split ))
1237
+ }
1238
+ return slice
1239
+ } else {
1240
+ return refValue
1241
+ }
1242
+ }
1243
+
1188
1244
func newInitError (name string ) error {
1189
1245
return fmt .Errorf ("field %q is not set" , name )
1190
1246
}
0 commit comments