-
Notifications
You must be signed in to change notification settings - Fork 0
/
form.go
64 lines (61 loc) · 1.58 KB
/
form.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package server
import (
"net/url"
"reflect"
"strconv"
"strings"
)
// copyStruct enumerates the exported fields in src and copies their values to
// the equivalent fields in dst. It is assumed that fields with the same name
// share the same type, otherwise a panic may result.
func copyStruct(src interface{}, dst interface{}) {
var (
srcType = reflect.TypeOf(src).Elem()
srcVal = reflect.ValueOf(src).Elem()
dstVal = reflect.ValueOf(dst).Elem()
)
for i := 0; i < srcType.NumField(); i++ {
fDstVal := dstVal.FieldByName(srcType.Field(i).Name)
if fDstVal.Kind() != reflect.Invalid {
fDstVal.Set(srcVal.Field(i))
}
}
}
// parseForm parses the supplied form, validates it, and stores the values in
// the supplied struct. The return value contains a map of all errors
// encountered during parsing.
func parseForm(form url.Values, v interface{}) map[string][]string {
var (
vType = reflect.TypeOf(v).Elem()
vVal = reflect.ValueOf(v).Elem()
errors = map[string][]string{}
)
for i := 0; i < vType.NumField(); i++ {
var (
fType = vType.Field(i)
fVal = vVal.Field(i)
s = form.Get(vType.Field(i).Name)
)
for _, tag := range strings.Split(fType.Tag.Get("form"), ",") {
switch tag {
case "required":
if len(s) == 0 {
errors[fType.Name] = append(
errors[fType.Name],
"this field is required",
)
}
}
}
switch fVal.Kind() {
case reflect.String:
fVal.SetString(s)
case reflect.Int64:
iVal, _ := strconv.ParseInt(s, 10, 64)
fVal.SetInt(iVal)
case reflect.Bool:
fVal.SetBool(len(s) > 0)
}
}
return errors
}