Skip to content
Snippets Groups Projects
Commit 0baa3151 authored by Danis Kirasirov's avatar Danis Kirasirov
Browse files

wip

parent 93fdc42e
No related branches found
No related tags found
No related merge requests found
...@@ -293,11 +293,11 @@ func (i *Item) Encode(ctx context.Context, s *schema.Schema) (*Item, error) { ...@@ -293,11 +293,11 @@ func (i *Item) Encode(ctx context.Context, s *schema.Schema) (*Item, error) {
return &res, nil return &res, nil
} }
func (i *Item) Decode(ctx context.Context, s *schema.Schema) (*Item, error) { func (i *Item) Decode(ctx context.Context, s *schema.Schema, opts ...field.EncodeOption) (*Item, error) {
res := *i res := *i
var err error var err error
if i.Data != nil { if i.Data != nil {
res.Data, err = s.Decode(ctx, i.Data) res.Data, err = s.Decode(ctx, i.Data, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -309,7 +309,7 @@ func (i *Item) Decode(ctx context.Context, s *schema.Schema) (*Item, error) { ...@@ -309,7 +309,7 @@ func (i *Item) Decode(ctx context.Context, s *schema.Schema) (*Item, error) {
res.Translations[l] = v res.Translations[l] = v
continue continue
} }
dt, err := schema.Decode(ctx, s, v) dt, err := schema.Decode(ctx, s, v, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -120,6 +120,19 @@ func (ArrayType) IsEmpty(v interface{}) bool { ...@@ -120,6 +120,19 @@ func (ArrayType) IsEmpty(v interface{}) bool {
// return nil // return nil
//} //}
func (ArrayType) NonStrictConverter(_ context.Context, _ *Field, v interface{}) interface{} {
if v == nil {
return nil
}
// Если в данных хранится не слайс или массив, преобразуем в слайс из одного элемента
if arr := reflect.ValueOf(v); arr.Kind() != reflect.Slice && arr.Kind() != reflect.Array {
return []interface{}{v}
}
return v
}
func (ArrayType) Walk(ctx context.Context, field *Field, v interface{}, fn WalkFunc, opts *WalkOptions) (interface{}, bool, error) { func (ArrayType) Walk(ctx context.Context, field *Field, v interface{}, fn WalkFunc, opts *WalkOptions) (interface{}, bool, error) {
var changed bool var changed bool
params, ok := field.Params.(*ArrayParameters) params, ok := field.Params.(*ArrayParameters)
......
...@@ -14,18 +14,42 @@ type Encoder interface { ...@@ -14,18 +14,42 @@ type Encoder interface {
Encode(ctx context.Context, field *Field, v interface{}) (interface{}, error) Encode(ctx context.Context, field *Field, v interface{}) (interface{}, error)
} }
func Decode(ctx context.Context, w Walker, v interface{}) (interface{}, error) { // NonStrictConverter определяет метод для преобразования данных в нестрогом режиме.
var err error type NonStrictConverter interface {
//if ctx == nil { NonStrictConverter(ctx context.Context, field *Field, v interface{}) interface{}
// ctx = NewContext() }
//}
// type EncodeOptions struct {
//if m, ok := v.(map[string]interface{}); ok { NonStrictMode bool
// ctx = ctx.ExtendEnv(m) }
// ctx.DisableConditions = true
//} 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) { 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 decoder, ok := f.GetType().(Decoder); ok {
if v, err = decoder.Decode(ctx, f, v); err != nil { if v, err = decoder.Decode(ctx, f, v); err != nil {
return return
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"math" "math"
"reflect" "reflect"
"strconv"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
...@@ -138,6 +139,25 @@ func (n NumberType) Encode(ctx context.Context, field *Field, v interface{}) (in ...@@ -138,6 +139,25 @@ func (n NumberType) Encode(ctx context.Context, field *Field, v interface{}) (in
return n.decode(ctx, field, v) return n.decode(ctx, field, v)
} }
func (NumberType) NonStrictConverter(_ context.Context, _ *Field, v interface{}) interface{} {
if v == nil {
return nil
}
// Если строка, пробуем преобразовать в число
if s, ok := v.(string); ok {
if i, err := strconv.ParseInt(s, 0, 64); err == nil {
return i
}
if f, err := strconv.ParseFloat(s, 64); err == nil {
return f
}
}
return v
}
func Number(format string, o ...interface{}) *Field { func Number(format string, o ...interface{}) *Field {
return NewField(&NumberParameters{Format: format}, o...) return NewField(&NumberParameters{Format: format}, o...)
} }
...@@ -58,6 +58,17 @@ func (StringType) Encode(_ context.Context, _ *Field, v interface{}) (interface{ ...@@ -58,6 +58,17 @@ func (StringType) Encode(_ context.Context, _ *Field, v interface{}) (interface{
return nil, fmt.Errorf("StringField encode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind()) return nil, fmt.Errorf("StringField encode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
} }
func (StringType) NonStrictConverter(_ context.Context, _ *Field, v interface{}) interface{} {
if v == nil {
return nil
}
if _, ok := v.(string); ok {
return v
}
return fmt.Sprintf("%v", v)
}
func String(o ...interface{}) *Field { func String(o ...interface{}) *Field {
return NewField(&StringParameters{}, o...) return NewField(&StringParameters{}, o...)
} }
...@@ -148,16 +148,17 @@ func (s *Schema) Evaluate(ctx context.Context, data map[string]interface{}) (res ...@@ -148,16 +148,17 @@ func (s *Schema) Evaluate(ctx context.Context, data map[string]interface{}) (res
return return
} }
func (s *Schema) Decode(ctx context.Context, v interface{}) (res map[string]interface{}, err error) { func (s *Schema) Decode(ctx context.Context, v interface{}, opt ...field.EncodeOption) (map[string]interface{}, error) {
if err = s.Load(ctx); err != nil { if err := s.Load(ctx); err != nil {
return nil, err return nil, err
} }
if v, err = Decode(ctx, s, v); err != nil { v, err := Decode(ctx, s, v, opt...)
if err != nil {
return nil, err return nil, err
} }
res, _ = v.(map[string]interface{}) res, _ := v.(map[string]interface{})
return return res, err
} }
func (s *Schema) Encode(ctx context.Context, v interface{}) (interface{}, error) { func (s *Schema) Encode(ctx context.Context, v interface{}) (interface{}, error) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment