Select Git revision
encode.go 2.16 KiB
package field
import (
"context"
"git.perx.ru/perxis/perxis-go/pkg/errors"
)
type Decoder interface {
Decode(ctx context.Context, field *Field, v interface{}) (interface{}, error)
}
type Encoder interface {
Encode(ctx context.Context, field *Field, v interface{}) (interface{}, error)
}
// NonStrictConverter определяет метод для преобразования данных в нестрогом режиме.
type NonStrictConverter interface {
NonStrictConverter(ctx context.Context, field *Field, v interface{}) interface{}
}
type EncodeOptions struct {
NonStrictMode bool
}
type EncodeOption func(opts *EncodeOptions)
// NonStrictMode указывает, что декодирование необходимо провести в нестрогом режиме.
func NonStrictMode() EncodeOption {
return func(opts *EncodeOptions) {
opts.NonStrictMode = true
}
}
func NewEncodeOptions(opt ...EncodeOption) *EncodeOptions {
opts := &EncodeOptions{}
for _, o := range opt {
o(opts)
}
return opts
}
func Decode(ctx context.Context, w Walker, v interface{}, opts ...EncodeOption) (interface{}, error) {
opt := NewEncodeOptions(opts...)
val, _, err := w.Walk(ctx, v, func(ctx context.Context, f *Field, v interface{}) (res WalkFuncResult, err error) {
if opt.NonStrictMode {
if converter, ok := f.GetType().(NonStrictConverter); ok {
v = converter.NonStrictConverter(ctx, f, v)
}
}
if decoder, ok := f.GetType().(Decoder); ok {
if v, err = decoder.Decode(ctx, f, v); err != nil {
return
}
res.Value = v
res.Changed = true
return
}
res.Value = v
return
})
if err != nil {
return nil, errors.Wrap(err, "decode error")
}
return val, nil
}