mirror of https://github.com/gofiber/fiber.git
82 lines
1.6 KiB
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
|
|
}
|