github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/struct_field.go (about)

     1  package jzon
     2  
     3  import (
     4  	"reflect"
     5  )
     6  
     7  /* see encoding/json
     8   * - some additional comments may be added
     9   * - some code may be slightly modified
    10   */
    11  
    12  type offset struct {
    13  	val   uintptr
    14  	rtype rtype
    15  }
    16  
    17  type field struct {
    18  	typ     reflect.Type
    19  	index   []int
    20  	offsets []offset
    21  
    22  	name           string
    23  	nameBytes      []byte // []byte(name)
    24  	nameBytesUpper []byte
    25  	equalFold      func(s, t []byte) bool // bytes.EqualFold or equivalent
    26  
    27  	tagged    bool
    28  	quoted    bool
    29  	omitEmpty bool
    30  
    31  	ptrType reflect.Type
    32  	// rtype   rtype
    33  }
    34  
    35  type structFields []field
    36  
    37  // byIndex sorts field by index sequence.
    38  type byIndex []field
    39  
    40  func (x byIndex) Len() int { return len(x) }
    41  
    42  func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
    43  
    44  func (x byIndex) Less(i, j int) bool {
    45  	for k, xik := range x[i].index {
    46  		if k >= len(x[j].index) {
    47  			return false
    48  		}
    49  		if xik != x[j].index[k] {
    50  			return xik < x[j].index[k]
    51  		}
    52  	}
    53  	return len(x[i].index) < len(x[j].index)
    54  }
    55  
    56  func dominantField(fields []field) (field, bool) {
    57  	// The fields are sorted in increasing index-length order, then by presence of tag.
    58  	// That means that the first field is the dominant one. We need only check
    59  	// for error cases: two fields at top level, either both tagged or neither tagged.
    60  	if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tagged == fields[1].tagged {
    61  		return field{}, false
    62  	}
    63  	return fields[0], true
    64  }