forked from gobuffalo/buffalo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
binding.go
69 lines (59 loc) · 1.66 KB
/
binding.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
package buffalo
import (
"encoding/json"
"encoding/xml"
"net/http"
"reflect"
"sync"
"github.com/gorilla/schema"
"github.com/markbates/pop/nulls"
"github.com/pkg/errors"
)
var binderLock = &sync.Mutex{}
var binders = map[string]BinderFunc{}
var schemaDecoder *schema.Decoder
// BinderFunc takes a request and binds it to an interface.
// If there is a problem it should return an error.
type BinderFunc func(*http.Request, interface{}) error
// RegisterBinder maps a request Content-Type (application/json)
// to a BinderFunc.
func RegisterBinder(contentType string, fn BinderFunc) {
binderLock.Lock()
defer binderLock.Unlock()
binders[contentType] = fn
}
func init() {
schemaDecoder = schema.NewDecoder()
schemaDecoder.IgnoreUnknownKeys(true)
schemaDecoder.ZeroEmpty(true)
// register the types in the nulls package with the decoder
nulls.RegisterWithSchema(func(i interface{}, fn func(s string) reflect.Value) {
schemaDecoder.RegisterConverter(i, fn)
})
sb := func(req *http.Request, value interface{}) error {
err := req.ParseForm()
if err != nil {
return errors.WithStack(err)
}
return schemaDecoder.Decode(value, req.PostForm)
}
binders["application/html"] = sb
binders["text/html"] = sb
binders["application/x-www-form-urlencoded"] = sb
}
func init() {
jb := func(req *http.Request, value interface{}) error {
return json.NewDecoder(req.Body).Decode(value)
}
binders["application/json"] = jb
binders["text/json"] = jb
binders["json"] = jb
}
func init() {
xb := func(req *http.Request, value interface{}) error {
return xml.NewDecoder(req.Body).Decode(value)
}
binders["application/xml"] = xb
binders["text/xml"] = xb
binders["xml"] = xb
}