Skip to content

Commit

Permalink
feat(binding): support custom struct tag (#2720)
Browse files Browse the repository at this point in the history
* feat(binding): support custom struct tag

Add function `binding.MapFormWithTag` (#2719)

* doc: add 'bind form-data with custom struct tag'

Add 'Bind form-data request with custom struct and custom tag' section (#2719)

* test(binding): add test for MapFromWithTag
  • Loading branch information
mtt0 committed Jun 29, 2021
1 parent e3ee01d commit 690aa2b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
55 changes: 55 additions & 0 deletions README.md
Expand Up @@ -2021,6 +2021,61 @@ enough to call binding at once.
can be called by `c.ShouldBind()` multiple times without any damage to
performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).

### Bind form-data request with custom struct and custom tag

```go
const (
customerTag = "url"
defaultMemory = 32 << 20
)

type customerBinding struct {}

func (customerBinding) Name() string {
return "form"
}

func (customerBinding) Bind(req *http.Request, obj interface{}) error {
if err := req.ParseForm(); err != nil {
return err
}
if err := req.ParseMultipartForm(defaultMemory); err != nil {
if err != http.ErrNotMultipart {
return err
}
}
if err := binding.MapFormWithTag(obj, req.Form, customerTag); err != nil {
return err
}
return validate(obj)
}

func validate(obj interface{}) error {
if binding.Validator == nil {
return nil
}
return binding.Validator.ValidateStruct(obj)
}

// Now we can do this!!!
// FormA is a external type that we can't modify it's tag
type FormA struct {
FieldA string `url:"field_a"`
}

func ListHandler(s *Service) func(ctx *gin.Context) {
return func(ctx *gin.Context) {
var urlBinding = customerBinding{}
var opt FormA
err := ctx.MustBindWith(&opt, urlBinding)
if err != nil {
...
}
...
}
}
```

### http2 server push

http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
Expand Down
4 changes: 4 additions & 0 deletions binding/form_mapping.go
Expand Up @@ -34,6 +34,10 @@ func mapForm(ptr interface{}, form map[string][]string) error {
return mapFormByTag(ptr, form, "form")
}

func MapFormWithTag(ptr interface{}, form map[string][]string, tag string) error {
return mapFormByTag(ptr, form, tag)
}

var emptyField = reflect.StructField{}

func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
Expand Down
9 changes: 9 additions & 0 deletions binding/form_mapping_test.go
Expand Up @@ -145,6 +145,15 @@ func TestMappingForm(t *testing.T) {
assert.Equal(t, int(6), s.F)
}

func TestMapFormWithTag(t *testing.T) {
var s struct {
F int `externalTag:"field"`
}
err := MapFormWithTag(&s, map[string][]string{"field": {"6"}}, "externalTag")
assert.NoError(t, err)
assert.Equal(t, int(6), s.F)
}

func TestMappingTime(t *testing.T) {
var s struct {
Time time.Time
Expand Down

0 comments on commit 690aa2b

Please sign in to comment.