Add ParseForm function
Showing
2 changed files
with
119 additions
and
0 deletions
| ... | @@ -4,7 +4,10 @@ import ( | ... | @@ -4,7 +4,10 @@ import ( |
| 4 | "fmt" | 4 | "fmt" |
| 5 | "github.com/russross/blackfriday" | 5 | "github.com/russross/blackfriday" |
| 6 | "html/template" | 6 | "html/template" |
| 7 | "net/url" | ||
| 8 | "reflect" | ||
| 7 | "regexp" | 9 | "regexp" |
| 10 | "strconv" | ||
| 8 | "strings" | 11 | "strings" |
| 9 | "time" | 12 | "time" |
| 10 | ) | 13 | ) |
| ... | @@ -179,3 +182,80 @@ func inSlice(v string, sl []string) bool { | ... | @@ -179,3 +182,80 @@ func inSlice(v string, sl []string) bool { |
| 179 | } | 182 | } |
| 180 | return false | 183 | return false |
| 181 | } | 184 | } |
| 185 | |||
| 186 | // parse form values to struct via tag | ||
| 187 | func ParseForm(form url.Values, obj interface{}) error { | ||
| 188 | objT := reflect.TypeOf(obj) | ||
| 189 | objV := reflect.ValueOf(obj) | ||
| 190 | if !(objT.Kind() == reflect.Ptr && objT.Elem().Kind() == reflect.Struct) { | ||
| 191 | return fmt.Errorf("%v must be a struct pointer", obj) | ||
| 192 | } | ||
| 193 | objT = objT.Elem() | ||
| 194 | objV = objV.Elem() | ||
| 195 | |||
| 196 | for i := 0; i < objT.NumField(); i++ { | ||
| 197 | fieldV := objV.Field(i) | ||
| 198 | if !fieldV.CanSet() { | ||
| 199 | continue | ||
| 200 | } | ||
| 201 | fieldT := objT.Field(i) | ||
| 202 | tag := fieldT.Tag.Get("form") | ||
| 203 | if len(tag) == 0 { | ||
| 204 | tag = fieldT.Name | ||
| 205 | } | ||
| 206 | value := form.Get(tag) | ||
| 207 | if len(value) == 0 { | ||
| 208 | continue | ||
| 209 | } | ||
| 210 | |||
| 211 | switch fieldT.Type.Kind() { | ||
| 212 | case reflect.Bool: | ||
| 213 | b, err := strconv.ParseBool(value) | ||
| 214 | if err != nil { | ||
| 215 | return err | ||
| 216 | } | ||
| 217 | fieldV.SetBool(b) | ||
| 218 | case reflect.Int: | ||
| 219 | fallthrough | ||
| 220 | case reflect.Int8: | ||
| 221 | fallthrough | ||
| 222 | case reflect.Int16: | ||
| 223 | fallthrough | ||
| 224 | case reflect.Int32: | ||
| 225 | fallthrough | ||
| 226 | case reflect.Int64: | ||
| 227 | x, err := strconv.ParseInt(value, 10, 64) | ||
| 228 | if err != nil { | ||
| 229 | return err | ||
| 230 | } | ||
| 231 | fieldV.SetInt(x) | ||
| 232 | case reflect.Uint: | ||
| 233 | fallthrough | ||
| 234 | case reflect.Uint8: | ||
| 235 | fallthrough | ||
| 236 | case reflect.Uint16: | ||
| 237 | fallthrough | ||
| 238 | case reflect.Uint32: | ||
| 239 | fallthrough | ||
| 240 | case reflect.Uint64: | ||
| 241 | x, err := strconv.ParseUint(value, 10, 64) | ||
| 242 | if err != nil { | ||
| 243 | return err | ||
| 244 | } | ||
| 245 | fieldV.SetUint(x) | ||
| 246 | case reflect.Float32: | ||
| 247 | fallthrough | ||
| 248 | case reflect.Float64: | ||
| 249 | x, err := strconv.ParseFloat(value, 64) | ||
| 250 | if err != nil { | ||
| 251 | return err | ||
| 252 | } | ||
| 253 | fieldV.SetFloat(x) | ||
| 254 | case reflect.Interface: | ||
| 255 | fieldV.Set(reflect.ValueOf(value)) | ||
| 256 | case reflect.String: | ||
| 257 | fieldV.SetString(value) | ||
| 258 | } | ||
| 259 | } | ||
| 260 | return nil | ||
| 261 | } | ... | ... |
utils_test.go
0 → 100644
| 1 | package beego | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "net/url" | ||
| 5 | "testing" | ||
| 6 | ) | ||
| 7 | |||
| 8 | func TestParseForm(t *testing.T) { | ||
| 9 | type user struct { | ||
| 10 | Id int | ||
| 11 | tag string `form:tag` | ||
| 12 | Name interface{} `form:"username"` | ||
| 13 | Age int `form:"age"` | ||
| 14 | Email string | ||
| 15 | } | ||
| 16 | |||
| 17 | u := user{} | ||
| 18 | form := url.Values{ | ||
| 19 | "tag": []string{"no"}, | ||
| 20 | "username": []string{"test"}, | ||
| 21 | "age": []string{"40"}, | ||
| 22 | "Email": []string{"test@gmail.com"}, | ||
| 23 | } | ||
| 24 | if err := ParseForm(form, u); err == nil { | ||
| 25 | t.Fatal("nothing will be changed") | ||
| 26 | } | ||
| 27 | if err := ParseForm(form, &u); err != nil { | ||
| 28 | t.Fatal(err) | ||
| 29 | } | ||
| 30 | if u.Name.(string) != "test" { | ||
| 31 | t.Error("should be equal") | ||
| 32 | } | ||
| 33 | if u.Age != 40 { | ||
| 34 | t.Error("should be equal") | ||
| 35 | } | ||
| 36 | if u.Email != "test@gmail.com" { | ||
| 37 | t.Error("should be equal") | ||
| 38 | } | ||
| 39 | } |
-
Please register or sign in to post a comment