Skip to content

Commit

Permalink
bind: add support for simple nested structs
Browse files Browse the repository at this point in the history
  • Loading branch information
efectn committed Sep 1, 2024
1 parent f19d747 commit 1f8459d
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
15 changes: 13 additions & 2 deletions bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,24 @@ type fieldTextDecoder struct {
}

func (d *fieldTextDecoder) Decode(ctx Ctx, reqValue reflect.Value) error {
field := reqValue.Field(d.fieldIndex)

// Support for sub fields
if len(d.subFieldDecoders) > 0 {
for _, subFieldDecoder := range d.subFieldDecoders {
err := subFieldDecoder.Decode(ctx, field)
if err != nil {
return err

Check warning on line 63 in bind.go

View check run for this annotation

Codecov / codecov/patch

bind.go#L63

Added line #L63 was not covered by tests
}
}
return nil
}

text := d.get(ctx, d.reqKey)
if text == "" {
return nil
}

field := reqValue.Field(d.fieldIndex)

if d.isTextMarshaler {
unmarshaler, ok := field.Addr().Interface().(encoding.TextUnmarshaler)
if !ok {
Expand Down
41 changes: 41 additions & 0 deletions bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,48 @@ func Test_Bind_BasicType(t *testing.T) {
U: []uint{99},
S: []string{"john"},
}, q2)
}

func Test_Bind_NestedStruct(t *testing.T) {
t.Parallel()

app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})

type AddressPayload struct {
Country string `query:"country"`
Country2 string `respHeader:"country"`
}

type Address struct {
City string `query:"city"`
Zip int `query:"zip"`
Payload AddressPayload `query:"payload"`
}

type User struct {
Name string `query:"name"`
Age int `query:"age"`
Address Address `query:"address"`
}

c.Request().URI().SetQueryString("name=john&age=30&address.city=NY&address.zip=10001&address.payload.country=US&address.payload.country2=US")

var u User
require.NoError(t, c.Bind().Req(&u).Err())

require.Equal(t, User{
Name: "john",
Age: 30,
Address: Address{
City: "NY",
Zip: 10001,
Payload: AddressPayload{
Country: "US",
Country2: "",
},
},
}, u)
}

// go test -run Test_Bind_Query -v
Expand Down
9 changes: 7 additions & 2 deletions binder_compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ func compileFieldDecoder(field reflect.StructField, index int, opt bindCompileOp
// If parent tag scope is present, just override it and append the parent tag content
var tagContent string
if parent != nil {
tagScope = parent.tagScope
if tagScope != parent.tagScope {
return nil, nil
}

if parent.isSlice {
tagContent = parent.tagContent + ".NUM." + field.Tag.Get(tagScope)
} else {
Expand Down Expand Up @@ -185,7 +188,9 @@ func compileTextBasedDecoder(field reflect.StructField, index int, tagScope, tag
return nil, err

Check warning on line 188 in binder_compile.go

View check run for this annotation

Codecov / codecov/patch

binder_compile.go#L188

Added line #L188 was not covered by tests
}

decoders = append(decoders, dec)
if dec != nil {
decoders = append(decoders, dec)
}
}

fieldDecoder.subFieldDecoders = decoders
Expand Down

0 comments on commit 1f8459d

Please sign in to comment.