diff --git a/structs/field.go b/structs/field.go index d39fdcc..9c683a2 100644 --- a/structs/field.go +++ b/structs/field.go @@ -2,6 +2,7 @@ package structs import ( "reflect" + "strings" "github.com/charlienet/go-mixed/expr" ) @@ -20,10 +21,20 @@ func parseField(fi reflect.StructField, opt option) field { name: fi.Name, tagName: expr.If(isValidTag(name), name, expr.If(opt.NameConverter != nil, opt.NameConverter(fi.Name), fi.Name)), ignoreEmpty: opt.IgnoreEmpty || (opts.Contains("omitempty") && opt.Omitempty), - ignore: name == "-" && opt.Ignore, + ignore: (name == "-" && opt.Ignore) || isSkipField(fi.Name, opt.SkipFields), } } func (f field) shouldIgnore(s reflect.Value) bool { return f.ignore || (s.IsZero() && f.ignoreEmpty) } + +func isSkipField(name string, skips []string) bool { + for _, v := range skips { + if strings.EqualFold(v, name) { + return true + } + } + + return false +} diff --git a/structs/map_test.go b/structs/map_test.go index 0ad61e4..c80f496 100644 --- a/structs/map_test.go +++ b/structs/map_test.go @@ -21,9 +21,21 @@ func TestStructToMap(t *testing.T) { OmitEmpty: 0, } - t.Log(structs.ToMap(o, structs.TagName("struct"))) - t.Log(structs.ToMap(o, structs.IgnoreEmpty())) - t.Log(structs.ToMap(o, structs.Omitempty())) - t.Log(structs.ToMap(o, structs.Lcfirst())) - t.Log(structs.ToMap(o, structs.Camel2Case())) + t.Log(structs.Struct2Map(o, structs.TagName("struct"))) + t.Log(structs.Struct2Map(o, structs.IgnoreEmpty())) + t.Log(structs.Struct2Map(o, structs.Omitempty())) + t.Log(structs.Struct2Map(o, structs.Lcfirst())) + t.Log(structs.Struct2Map(o, structs.Camel2Case())) +} + +func TestMapToStruct(t *testing.T) { + +} + +func TestMap2Map(t *testing.T) { + source := map[string]any{ + "Abc": 143, + } + + structs.New(source) } diff --git a/structs/options.go b/structs/options.go index fa58354..372e84b 100644 --- a/structs/options.go +++ b/structs/options.go @@ -7,6 +7,7 @@ import ( type optionFunc func(*option) type option struct { + SkipFields []string TagName string DeepCopy bool Omitempty bool @@ -39,6 +40,18 @@ func DeepCopy() optionFunc { } } +func SkipField(field string) optionFunc { + return func(o *option) { + o.SkipFields = append(o.SkipFields, field) + } +} + +func SkipFields(fields []string) optionFunc { + return func(o *option) { + o.SkipFields = append(o.SkipFields, fields...) + } +} + func Lcfirst() optionFunc { return func(o *option) { o.NameConverter = json.Lcfirst diff --git a/structs/structs.go b/structs/structs.go index b8e7bef..2c29966 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -67,6 +67,12 @@ func (s *Struct) ToMap() map[string]any { return m } +/* + struct -> map + struct -> struct + map -> struct + map -> map +*/ func (s *Struct) Copy(dest any) error { to := indirect(reflect.ValueOf(dest)) @@ -102,7 +108,11 @@ func (s *Struct) getByName(name string) (field, bool) { return field{}, false } -func ToMap(o any, opts ...optionFunc) map[string]any { +func Map2Struct(o map[string]any, dst any) { + +} + +func Struct2Map(o any, opts ...optionFunc) map[string]any { return New(o, opts...).ToMap() } @@ -112,6 +122,15 @@ func Copy(source, dst any, opts ...optionFunc) { func parseFields(t reflect.Value, opt option) []field { typ := indirectType(t.Type()) + + if typ.Kind() == reflect.Struct { + return parseStructFields(typ, opt) + } + + return nil +} + +func parseStructFields(typ reflect.Type, opt option) []field { num := typ.NumField() fields := make([]field, 0, num) for i := 0; i < num; i++ {