-
Notifications
You must be signed in to change notification settings - Fork 0
/
form.go
86 lines (70 loc) · 1.89 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package ring
import (
"io"
"net/http"
"github.com/pasztorpisti/qs"
"github.com/mitchellh/mapstructure"
)
type (
// MultipartFormBinder parses the request body as "multipart/form-data",
// and binds it to the provided model using the \`multipart:""\` struct
// tag.
//
// See [mapstructure.Decoder] for more decoding details.
MultipartFormBinder[T any] struct{
MaxMemory int64
}
// URLEncodedFormBinder parses the request body as "application/x-www-formurlencoded",
// and binds it to the provided model using the \`qs:""\` struct
// tag.
//
// See [qs.QSUnmarshaler] for more decoding details
URLEncodedFormBinder[T any] struct {
Options *qs.UnmarshalOptions
}
)
// Bind implements Binder.
func (binder *MultipartFormBinder[T]) Bind(r *http.Request, model T) error {
if err := r.ParseMultipartForm(binder.MaxMemory); err != nil {
return err
}
reader, err := r.MultipartReader()
if err != nil {
return err
}
form, err := reader.ReadForm(binder.MaxMemory)
if err != nil {
return err
}
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
TagName: "multipart",
Result: model,
})
if err != nil {
return err
}
if err := dec.Decode(form.Value); err != nil {
return err
}
if err := dec.Decode(form.File); err != nil {
return err
}
return nil
}
// Bind implements Binder.
func (binder *URLEncodedFormBinder[T]) Bind(r *http.Request, model T) error {
body, err := io.ReadAll(r.Body)
if err != nil {
return err
}
dec := qs.NewUnmarshaler(binder.Options)
err = dec.Unmarshal(model, string(body))
if err != nil {
return err
}
return nil
}
var (
_ Binder[any] = (*MultipartFormBinder[any])(nil)
_ Binder[any] = (*URLEncodedFormBinder[any])(nil)
)