github.com/hedzr/evendeep@v0.4.8/tag.go (about) 1 package evendeep 2 3 import ( 4 "reflect" 5 "strings" 6 7 "github.com/hedzr/evendeep/flags" 8 "github.com/hedzr/evendeep/flags/cms" 9 ) 10 11 // parseFieldTags gets the struct field tag string by 'tagKeyName', and 12 // parse the string into a fieldTags object and return it. 13 func parseFieldTags(tag reflect.StructTag, tagName string) *fieldTags { 14 t := &fieldTags{} 15 t.Parse(tag, tagName) 16 return t 17 } 18 19 // fieldTags collect the flags and others which are parsed from a struct field tags definition. 20 // 21 // type sample struct { 22 // SomeName string `copy:"someName,omitempty"` 23 // IgnoredName string `copy:"-"` 24 // } 25 type fieldTags struct { 26 flags flags.Flags `copy:"zeroIfEq"` 27 28 converter *ValueConverter `yaml:"-,omitempty"` //nolint:unused //future 29 copier *ValueCopier `yaml:"-,omitempty"` //nolint:unused //future 30 nameConverter nameConverterFunc `yaml:"-,omitempty"` 31 32 // nameConvertRule: 33 // "-" ignore 34 // "dstName" from source field to 'dstName' field (thinking about name converters too) 35 // "->dstName" from source field to 'dstName' field (thinking about name converters too) 36 // "srcName->dstName" from 'srcName' to 'dstName' field 37 nameConvertRule flags.NameConvertRule // first section in struct field tag, such as: "someName,must,..." 38 } 39 40 type nameConverterFunc func(source string, ctx *NameConverterContext) (target string, ok bool) 41 42 func (f *fieldTags) String() string { 43 var a []string 44 if f != nil && f.flags != nil { 45 for k := range f.flags { 46 a = append(a, k.String()) 47 } 48 } 49 return strings.Join(a, ", ") 50 } 51 52 func (f *fieldTags) isFlagExists(ftf cms.CopyMergeStrategy) bool { 53 if f == nil { 54 return false 55 } 56 return f.flags[ftf] 57 } 58 59 func (f *fieldTags) isFlagIgnored() bool { return f.isFlagExists(cms.Ignore) } 60 func (f *fieldTags) isFlagFlat() bool { return f.isFlagExists(cms.Flat) } 61 62 func (f *fieldTags) Parse(s reflect.StructTag, tagName string) { 63 f.flags, f.nameConvertRule = flags.Parse(s, tagName) 64 } 65 66 func (f *fieldTags) CalcSourceName(dstName string) (srcName string, ok bool) { 67 ok = f.nameConvertRule.Valid() 68 srcName = strget(f.nameConvertRule.FromName(), dstName) 69 // dbglog.Log(" FromName: %v (Default to %v) | RETURN: %v", f.nameConvertRule.FromName(), dstName, srcName) 70 return 71 } 72 73 func (f *fieldTags) CalcTargetName(srcName string, ctx *NameConverterContext) (dstName string, ok bool) { 74 if f.nameConverter != nil { 75 dstName, ok = f.nameConverter(srcName, ctx) 76 if ok { 77 return 78 } 79 } 80 ok = f.nameConvertRule.Valid() 81 dstName = strget(f.nameConvertRule.ToName(), srcName) 82 return 83 } 84 85 func strget(s, def string) string { 86 if s == "" { 87 return def 88 } 89 return s 90 }