Skip to content

Commit

Permalink
export the Form and Query decoders in order to be customized by Iris …
Browse files Browse the repository at this point in the history
…users and ignore unknown url query parameters instead of giving an ErrPath

relative to: kataras/iris#1566
  • Loading branch information
kataras committed Jul 24, 2020
1 parent 1f5dc3f commit 898d805
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 15 deletions.
15 changes: 10 additions & 5 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ type Decoder struct {

// AddAliasTag adds a tag used to locate custom field aliases.
// Defaults are "schema", "form" and "url".
func (d *Decoder) AddAliasTag(tag ...string) {
func (d *Decoder) AddAliasTag(tag ...string) *Decoder {
d.cache.tags = append(d.cache.tags, tag...)
return d
}

// SetAliasTag overrides the tags.
func (d *Decoder) SetAliasTag(tag ...string) {
func (d *Decoder) SetAliasTag(tag ...string) *Decoder {
d.cache.tags = tag
return d
}

// ZeroEmpty controls the behaviour when the decoder encounters empty values
Expand All @@ -43,8 +45,9 @@ func (d *Decoder) SetAliasTag(tag ...string) {
//
// The default value is false, that is empty values do not change
// the value of the struct field.
func (d *Decoder) ZeroEmpty(z bool) {
func (d *Decoder) ZeroEmpty(z bool) *Decoder {
d.zeroEmpty = z
return d
}

// IgnoreUnknownKeys controls the behaviour when the decoder encounters unknown
Expand All @@ -55,13 +58,15 @@ func (d *Decoder) ZeroEmpty(z bool) {
// will still be decoded in to the target struct.
//
// To preserve backwards compatibility, the default value is false.
func (d *Decoder) IgnoreUnknownKeys(i bool) {
func (d *Decoder) IgnoreUnknownKeys(i bool) *Decoder {
d.ignoreUnknownKeys = i
return d
}

// RegisterConverter registers a converter function for a custom type.
func (d *Decoder) RegisterConverter(value interface{}, converterFunc Converter) {
func (d *Decoder) RegisterConverter(value interface{}, converterFunc Converter) *Decoder {
d.cache.registerConverter(value, converterFunc)
return d
}

// Decode decodes a map[string][]string to a struct.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/iris-contrib/schema

go 1.12
go 1.14
15 changes: 6 additions & 9 deletions schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ package schema

var (
defaultDecoder = NewDecoder() // form, url, schema.
formDecoder = NewDecoder()
queryDecoder = NewDecoder()
// Form Decoder. The default instance for DecodeForm function.
Form = NewDecoder().SetAliasTag("form")
// Query Decoder. The default instance for DecodeQuery function.
Query = NewDecoder().SetAliasTag("url").IgnoreUnknownKeys(true) // allow unknown url queries.
)

func init() {
formDecoder.SetAliasTag("form")
queryDecoder.SetAliasTag("url")
}

// Decode maps "values" to "ptr".
// With one of the "form", "url" or "schema" tag fields that can override the field's name mapping to key.
func Decode(values map[string][]string, ptr interface{}) error {
Expand All @@ -20,13 +17,13 @@ func Decode(values map[string][]string, ptr interface{}) error {
// DecodeForm maps "values" to "ptr".
// With "form" tag for fields.
func DecodeForm(values map[string][]string, ptr interface{}) error {
return formDecoder.Decode(ptr, values)
return Form.Decode(ptr, values)
}

// DecodeQuery maps "values" to "ptr".
// With "url" tag for fields.
func DecodeQuery(values map[string][]string, ptr interface{}) error {
return queryDecoder.Decode(ptr, values)
return Query.Decode(ptr, values)
}

// IsErrPath reports whether the incoming error is type of unknown field passed,
Expand Down
44 changes: 44 additions & 0 deletions schema_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// package schema_test black box testing
package schema_test

import (
"testing"

"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/httptest"
)

type testRequest struct {
Username string `form:"test_username" json:"test_username"`
Data []testData `form:"test_data" json:"test_data"`
Other int `form:"test_other" json:"test_other"`
}

type testData struct {
Name string `form:"test_data_name" json:"test_data_name"`
}

func TestSchemaSliceFieldTag(t *testing.T) {
app := iris.New()
app.Post("/", func(ctx iris.Context) {
var p testRequest
if err := ctx.ReadForm(&p); err != nil && iris.IsErrPath(err) {
t.Fatal(err)
}

ctx.JSON(p)
})

payload := testRequest{
Username: "test username",
Data: []testData{
{Name: "test data name 1"},
{Name: "test data name 2"},
{Name: "test data name 3"},
},
Other: 42,
}

e := httptest.New(t, app)
e.POST("/").WithForm(payload).Expect().Status(iris.StatusOK).JSON().Equal(payload)
}

0 comments on commit 898d805

Please sign in to comment.