github.com/searKing/golang/go@v1.2.117/encoding/internal/tag/structTagFunc.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tag
     6  
     7  import (
     8  	"reflect"
     9  
    10  	reflect2 "github.com/searKing/golang/go/reflect"
    11  )
    12  
    13  type structTagFunc struct {
    14  	fields       []field
    15  	fieldTagFunc []tagFunc
    16  }
    17  
    18  func (se *structTagFunc) handle(state *tagState, v reflect.Value, opts tagOpts) (isUserDefined bool) {
    19  	isUserDefined = false
    20  
    21  	for i, f := range se.fields {
    22  		fv := reflect2.ValueByStructFieldIndex(v, f.index)
    23  		if !fv.IsValid() && reflect2.IsEmptyValue(fv) {
    24  			continue
    25  		}
    26  		field := v.FieldByIndex(se.fields[i].index)
    27  
    28  		//判断是否为可取指,可导出字段
    29  		if !field.CanAddr() || !field.CanInterface() {
    30  			continue
    31  		}
    32  
    33  		// continue if a userDefined func has been called
    34  		if isFieldTagFuncUserDefined := se.fieldTagFunc[i](state, fv, opts); isFieldTagFuncUserDefined {
    35  			continue
    36  		}
    37  
    38  		tagFn := opts.TagHandler
    39  		if tagFn != nil {
    40  			if err := tagFn(field, se.fields[i].structTag); err != nil {
    41  				state.error(&TaggerError{v.Type(), err})
    42  				return
    43  			}
    44  		}
    45  	}
    46  	return
    47  }
    48  
    49  func newStructTagFunc(t reflect.Type) tagFunc {
    50  	fields := cachedTypeFields(t)
    51  	se := &structTagFunc{
    52  		fields:       fields,
    53  		fieldTagFunc: make([]tagFunc, len(fields)),
    54  	}
    55  	for i, f := range fields {
    56  		se.fieldTagFunc[i] = typeTagFunc(reflect2.TypeByStructFieldIndex(t, f.index))
    57  	}
    58  	return se.handle
    59  }