File: field.go

package info (click to toggle)
golang-github-francoispqt-gojay 1.2.13-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 1,456 kB
  • sloc: makefile: 86
file content (168 lines) | stat: -rw-r--r-- 5,269 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package codegen

import (
	"fmt"
	"github.com/viant/toolbox"
	"strings"
)

//Field represents a field.
type Field struct {
	Key                string
	Init               string
	OmitEmpty          string
	TimeLayout         string
	NullType           string
	Name               string
	Accessor           string
	Mutator            string
	Receiver           string //alias and type name
	Alias              string //object alias name
	Var                string //variable for this field
	Type               string
	RawType            string
	HelperType         string
	ComponentType      string
	RawComponentType   string
	IsPointerComponent bool

	PointerModifier     string //takes field pointer, "&" if field is not a pointer type
	DereferenceModifier string //take pointer value, i.e "*" if field has a pointer type

	ComponentPointerModifier     string //takes item pointer if needed,i.e
	ComponentDereferenceModifier string //de reference value if needed, i.e
	ComponentInitModifier        string //takes item pointer if type is not a pointer type
	ComponentInit                string //initialises component type

	DecodingMethod  string
	EncodingMethod  string
	PoolName        string //pool name associated with this field
	ResetDependency string
	Reset           string
	IsAnonymous     bool
	IsPointer       bool
	IsSlice         bool

	GojayMethod string
}

//NewField returns a new field
func NewField(owner *Struct, field *toolbox.FieldInfo, fieldType *toolbox.TypeInfo) (*Field, error) {
	typeName := normalizeTypeName(field.TypeName)
	var result = &Field{
		IsAnonymous:        field.IsAnonymous,
		Name:               field.Name,
		RawType:            field.TypeName,
		IsPointer:          field.IsPointer,
		Key:                getJSONKey(owner.options, field),
		Receiver:           owner.Alias + " *" + owner.TypeInfo.Name,
		Type:               typeName,
		Mutator:            owner.Alias + "." + field.Name,
		Accessor:           owner.Alias + "." + field.Name,
		ComponentType:      field.ComponentType,
		IsPointerComponent: field.IsPointerComponent,
		Var:                firstLetterToLowercase(field.Name),
		Init:               fmt.Sprintf("%v{}", typeName),
		TimeLayout:         "time.RFC3339",
		IsSlice:            field.IsSlice,
		PoolName:           getPoolName(field.TypeName),
		Alias:              owner.Alias,
		Reset:              "nil",
	}
	var err error
	if field.IsPointer {
		result.DereferenceModifier = "*"
		result.Init = "&" + result.Init
	} else {
		result.PointerModifier = "&"

	}
	if field.IsSlice {
		result.HelperType = getSliceHelperTypeName(field.ComponentType, field.IsPointerComponent)
		result.PoolName = getPoolName(field.ComponentType)
	} else if fieldType != nil {
		result.HelperType = getSliceHelperTypeName(fieldType.Name, field.IsPointerComponent)
	}

	if options := getTagOptions(field.Tag, "timeLayout"); len(options) > 0 {
		result.TimeLayout = wrapperIfNeeded(options[0], `"`)
	} else if options := getTagOptions(field.Tag, "timeFormat"); len(options) > 0 {
		result.TimeLayout = wrapperIfNeeded(toolbox.DateFormatToLayout(options[0]), `"`)
	}
	if strings.Contains(field.Tag, "omitempty") {
		result.OmitEmpty = "OmitEmpty"
	}
	if strings.Contains(field.Tag, "nullempty") {
		result.OmitEmpty = "NullEmpty"
	}

	if owner.options.PoolObjects {
		if field.IsPointer && !strings.HasSuffix(field.TypeName, ".Time") && !strings.Contains(field.TypeName, "sql.Null") {
			poolName := getPoolName(field.TypeName)
			result.Init = fmt.Sprintf(`%v.Get().(*%v)`, poolName, field.TypeName)
		}
	}

	encodingMethod := field.ComponentType
	if encodingMethod == "" {
		encodingMethod = result.Type
	}
	result.DecodingMethod = firstLetterToUppercase(encodingMethod)
	result.EncodingMethod = firstLetterToUppercase(encodingMethod)

	switch typeName {
	case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64":
		result.Reset = "0"
	case "float32", "float64":
		result.Reset = "0.0"
	case "string":
		result.Reset = `""`

	case "bool":
		result.Reset = "false"
	default:
		if field.IsSlice && owner.Type(field.ComponentType) != nil {
			var itemPointer = ""
			if !field.IsPointerComponent {
				itemPointer = "&"
			}
			result.ResetDependency, err = expandFieldTemplate(poolSliceInstanceRelease, struct {
				PoolName        string
				Accessor        string
				PointerModifier string
			}{PoolName: result.PoolName, Accessor: result.Accessor, PointerModifier: itemPointer})
			if err != nil {
				return nil, err
			}

		} else if field.IsPointer && fieldType != nil {
			result.ResetDependency, err = expandFieldTemplate(poolInstanceRelease, struct {
				PoolName string
				Accessor string
			}{PoolName: result.PoolName, Accessor: result.Accessor})
			if err != nil {
				return nil, err
			}
		}

	}
	if field.IsSlice || field.IsPointer {
		result.Reset = "nil"
	}

	if result.IsPointerComponent {
		result.ComponentInit = "&" + result.ComponentType + "{}"
		result.RawComponentType = "*" + result.ComponentType

		result.ComponentDereferenceModifier = "*"
		result.ComponentInitModifier = "&"

	} else {
		result.ComponentInit = result.ComponentType + "{}"
		result.RawComponentType = result.ComponentType

		result.ComponentPointerModifier = "&"
	}

	return result, nil
}