-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.go
84 lines (75 loc) · 1.92 KB
/
app.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package controllers
import (
"fmt"
"github.com/revel/revel"
"gopkg.in/mgo.v2/bson"
"reflect"
"strings"
)
func init() {
revel.KindBinders[reflect.Struct] = myBinder
revel.TypeBinders[reflect.TypeOf(bson.NewObjectId())] = revel.Binder{
Bind: func(params *revel.Params, name string, typ reflect.Type) reflect.Value {
values, ok := params.Values[name]
if !ok || len(values) == 0 || !bson.IsObjectIdHex(values[0]) {
return reflect.Zero(typ)
}
var value bson.ObjectId = bson.ObjectIdHex(values[0])
return reflect.ValueOf(value)
},
Unbind: nil,
}
}
type App struct {
BaseCollection
}
func (c App) Index() revel.Result {
return c.Render()
}
func (a App) Role() revel.Result {
return a.Render()
}
var myBinder = revel.Binder{
bindStruct,
unbindStruct,
}
func nextKey(key string) string {
fieldLen := strings.IndexAny(key, ".[")
if fieldLen == -1 {
return key
}
return key[:fieldLen]
}
func bindStruct(params *revel.Params, name string, typ reflect.Type) reflect.Value {
result := reflect.New(typ).Elem()
fieldValues := make(map[string]reflect.Value)
for key, _ := range params.Values {
suffix := strings.TrimSpace(key)
fieldName := nextKey(suffix)
if _, ok := fieldValues[fieldName]; !ok {
fieldValue := result.FieldByName(fieldName)
if !fieldValue.IsValid() {
continue
}
if !fieldValue.CanSet() {
continue
}
boundVal := revel.Bind(params, fieldName, fieldValue.Type())
fieldValue.Set(boundVal)
fieldValues[fieldName] = boundVal
}
}
return result
}
func unbindStruct(output map[string]string, name string, iface interface{}) {
val := reflect.ValueOf(iface)
typ := val.Type()
for i := 0; i < val.NumField(); i++ {
structField := typ.Field(i)
fieldValue := val.Field(i)
// PkgPath is specified to be empty exactly for exported fields.
if structField.PkgPath == "" {
revel.Unbind(output, fmt.Sprintf("%s.%s", name, structField.Name), fieldValue.Interface())
}
}
}