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  }