aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/fxamacker/cbor/v2/structfields.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/fxamacker/cbor/v2/structfields.go')
-rw-r--r--vendor/github.com/fxamacker/cbor/v2/structfields.go260
1 files changed, 0 insertions, 260 deletions
diff --git a/vendor/github.com/fxamacker/cbor/v2/structfields.go b/vendor/github.com/fxamacker/cbor/v2/structfields.go
deleted file mode 100644
index 81228acf0..000000000
--- a/vendor/github.com/fxamacker/cbor/v2/structfields.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) Faye Amacker. All rights reserved.
-// Licensed under the MIT License. See LICENSE in the project root for license information.
-
-package cbor
-
-import (
- "reflect"
- "sort"
- "strings"
-)
-
-type field struct {
- name string
- nameAsInt int64 // used to decoder to match field name with CBOR int
- cborName []byte
- cborNameByteString []byte // major type 2 name encoding iff cborName has major type 3
- idx []int
- typ reflect.Type
- ef encodeFunc
- ief isEmptyFunc
- typInfo *typeInfo // used to decoder to reuse type info
- tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields)
- omitEmpty bool // used to skip empty field
- keyAsInt bool // used to encode/decode field name as int
-}
-
-type fields []*field
-
-// indexFieldSorter sorts fields by field idx at each level, breaking ties with idx depth.
-type indexFieldSorter struct {
- fields fields
-}
-
-func (x *indexFieldSorter) Len() int {
- return len(x.fields)
-}
-
-func (x *indexFieldSorter) Swap(i, j int) {
- x.fields[i], x.fields[j] = x.fields[j], x.fields[i]
-}
-
-func (x *indexFieldSorter) Less(i, j int) bool {
- iIdx, jIdx := x.fields[i].idx, x.fields[j].idx
- for k := 0; k < len(iIdx) && k < len(jIdx); k++ {
- if iIdx[k] != jIdx[k] {
- return iIdx[k] < jIdx[k]
- }
- }
- return len(iIdx) <= len(jIdx)
-}
-
-// nameLevelAndTagFieldSorter sorts fields by field name, idx depth, and presence of tag.
-type nameLevelAndTagFieldSorter struct {
- fields fields
-}
-
-func (x *nameLevelAndTagFieldSorter) Len() int {
- return len(x.fields)
-}
-
-func (x *nameLevelAndTagFieldSorter) Swap(i, j int) {
- x.fields[i], x.fields[j] = x.fields[j], x.fields[i]
-}
-
-func (x *nameLevelAndTagFieldSorter) Less(i, j int) bool {
- fi, fj := x.fields[i], x.fields[j]
- if fi.name != fj.name {
- return fi.name < fj.name
- }
- if len(fi.idx) != len(fj.idx) {
- return len(fi.idx) < len(fj.idx)
- }
- if fi.tagged != fj.tagged {
- return fi.tagged
- }
- return i < j // Field i and j have the same name, depth, and tagged status. Nothing else matters.
-}
-
-// getFields returns visible fields of struct type t following visibility rules for JSON encoding.
-func getFields(t reflect.Type) (flds fields, structOptions string) {
- // Get special field "_" tag options
- if f, ok := t.FieldByName("_"); ok {
- tag := f.Tag.Get("cbor")
- if tag != "-" {
- structOptions = tag
- }
- }
-
- // nTypes contains next level anonymous fields' types and indexes
- // (there can be multiple fields of the same type at the same level)
- flds, nTypes := appendFields(t, nil, nil, nil)
-
- if len(nTypes) > 0 {
-
- var cTypes map[reflect.Type][][]int // current level anonymous fields' types and indexes
- vTypes := map[reflect.Type]bool{t: true} // visited field types at less nested levels
-
- for len(nTypes) > 0 {
- cTypes, nTypes = nTypes, nil
-
- for t, idx := range cTypes {
- // If there are multiple anonymous fields of the same struct type at the same level, all are ignored.
- if len(idx) > 1 {
- continue
- }
-
- // Anonymous field of the same type at deeper nested level is ignored.
- if vTypes[t] {
- continue
- }
- vTypes[t] = true
-
- flds, nTypes = appendFields(t, idx[0], flds, nTypes)
- }
- }
- }
-
- sort.Sort(&nameLevelAndTagFieldSorter{flds})
-
- // Keep visible fields.
- j := 0 // index of next unique field
- for i := 0; i < len(flds); {
- name := flds[i].name
- if i == len(flds)-1 || // last field
- name != flds[i+1].name || // field i has unique field name
- len(flds[i].idx) < len(flds[i+1].idx) || // field i is at a less nested level than field i+1
- (flds[i].tagged && !flds[i+1].tagged) { // field i is tagged while field i+1 is not
- flds[j] = flds[i]
- j++
- }
-
- // Skip fields with the same field name.
- for i++; i < len(flds) && name == flds[i].name; i++ { //nolint:revive
- }
- }
- if j != len(flds) {
- flds = flds[:j]
- }
-
- // Sort fields by field index
- sort.Sort(&indexFieldSorter{flds})
-
- return flds, structOptions
-}
-
-// appendFields appends type t's exportable fields to flds and anonymous struct fields to nTypes .
-func appendFields(
- t reflect.Type,
- idx []int,
- flds fields,
- nTypes map[reflect.Type][][]int,
-) (
- _flds fields,
- _nTypes map[reflect.Type][][]int,
-) {
- for i := 0; i < t.NumField(); i++ {
- f := t.Field(i)
-
- ft := f.Type
- for ft.Kind() == reflect.Ptr {
- ft = ft.Elem()
- }
-
- if !isFieldExportable(f, ft.Kind()) {
- continue
- }
-
- tag := f.Tag.Get("cbor")
- if tag == "" {
- tag = f.Tag.Get("json")
- }
- if tag == "-" {
- continue
- }
-
- tagged := tag != ""
-
- // Parse field tag options
- var tagFieldName string
- var omitempty, keyasint bool
- for j := 0; tag != ""; j++ {
- var token string
- idx := strings.IndexByte(tag, ',')
- if idx == -1 {
- token, tag = tag, ""
- } else {
- token, tag = tag[:idx], tag[idx+1:]
- }
- if j == 0 {
- tagFieldName = token
- } else {
- switch token {
- case "omitempty":
- omitempty = true
- case "keyasint":
- keyasint = true
- }
- }
- }
-
- fieldName := tagFieldName
- if tagFieldName == "" {
- fieldName = f.Name
- }
-
- fIdx := make([]int, len(idx)+1)
- copy(fIdx, idx)
- fIdx[len(fIdx)-1] = i
-
- if !f.Anonymous || ft.Kind() != reflect.Struct || tagFieldName != "" {
- flds = append(flds, &field{
- name: fieldName,
- idx: fIdx,
- typ: f.Type,
- omitEmpty: omitempty,
- keyAsInt: keyasint,
- tagged: tagged})
- } else {
- if nTypes == nil {
- nTypes = make(map[reflect.Type][][]int)
- }
- nTypes[ft] = append(nTypes[ft], fIdx)
- }
- }
-
- return flds, nTypes
-}
-
-// isFieldExportable returns true if f is an exportable (regular or anonymous) field or
-// a nonexportable anonymous field of struct type.
-// Nonexportable anonymous field of struct type can contain exportable fields.
-func isFieldExportable(f reflect.StructField, fk reflect.Kind) bool { //nolint:gocritic // ignore hugeParam
- exportable := f.PkgPath == ""
- return exportable || (f.Anonymous && fk == reflect.Struct)
-}
-
-type embeddedFieldNullPtrFunc func(reflect.Value) (reflect.Value, error)
-
-// getFieldValue returns field value of struct v by index. When encountering null pointer
-// to anonymous (embedded) struct field, f is called with the last traversed field value.
-func getFieldValue(v reflect.Value, idx []int, f embeddedFieldNullPtrFunc) (fv reflect.Value, err error) {
- fv = v
- for i, n := range idx {
- fv = fv.Field(n)
-
- if i < len(idx)-1 {
- if fv.Kind() == reflect.Ptr && fv.Type().Elem().Kind() == reflect.Struct {
- if fv.IsNil() {
- // Null pointer to embedded struct field
- fv, err = f(fv)
- if err != nil || !fv.IsValid() {
- return fv, err
- }
- }
- fv = fv.Elem()
- }
- }
- }
- return fv, nil
-}