fiber/bind.go

82 lines
1.6 KiB
Go

package fiber
import (
"fmt"
"reflect"
"github.com/gofiber/fiber/v3/internal/bind"
)
type Binder interface {
UnmarshalFiberCtx(ctx Ctx) error
}
// decoder should set a field on reqValue
// it's created with field index
type decoder interface {
Decode(ctx Ctx, reqValue reflect.Value) error
}
type fieldCtxDecoder struct {
index int
fieldName string
fieldType reflect.Type
}
func (d *fieldCtxDecoder) Decode(ctx Ctx, reqValue reflect.Value) error {
v := reflect.New(d.fieldType)
unmarshaler := v.Interface().(Binder)
if err := unmarshaler.UnmarshalFiberCtx(ctx); err != nil {
return err
}
reqValue.Field(d.index).Set(v.Elem())
return nil
}
type fieldTextDecoder struct {
index int
parentIndex []int
fieldName string
tag string // query,param,header,respHeader ...
reqField string
et reflect.Type
dec bind.TextDecoder
get func(c Ctx, key string, defaultValue ...string) string
}
func (d *fieldTextDecoder) Decode(ctx Ctx, reqValue reflect.Value) error {
text := d.get(ctx, d.reqField)
if text == "" {
return nil
}
var err error
for _, i := range d.parentIndex {
reqValue = reqValue.Field(i)
}
// Pointer support for struct elems
field := reqValue.Field(d.index)
if field.Kind() == reflect.Ptr {
elem := reflect.New(d.et)
err = d.dec.UnmarshalString(text, elem.Elem())
if err != nil {
return fmt.Errorf("unable to decode '%s' as %s: %w", text, d.reqField, err)
}
field.Set(elem)
return nil
}
// Non-pointer elems
err = d.dec.UnmarshalString(text, field)
if err != nil {
return fmt.Errorf("unable to decode '%s' as %s: %w", text, d.reqField, err)
}
return nil
}