Skip to content

Commit eeb389a

Browse files
authored
internal: simplify structpath to eager initialize (#3594)
## Changes Simplify structpath by removing lazy initialization. ## Why Easier to extend this package. ## Tests Existing tests. Ran benchmarks on structdiff and structwalk, there are no noticeable changes.
1 parent 87a3046 commit eeb389a

File tree

1 file changed

+13
-26
lines changed

1 file changed

+13
-26
lines changed

libs/structdiff/structpath/path.go

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ import (
99
)
1010

1111
const (
12-
tagStruct = -1
13-
tagMapKey = -2
14-
tagUnresolvedStruct = -3
15-
tagAnyKey = -4
16-
tagAnyIndex = -5
12+
tagStruct = -1
13+
tagMapKey = -2
14+
tagAnyKey = -4
15+
tagAnyIndex = -5
1716
)
1817

1918
// PathNode represents a node in a path for struct diffing.
2019
// It can represent struct fields, map keys, or array/slice indices.
2120
type PathNode struct {
2221
prev *PathNode
23-
jsonTag structtag.JSONTag // For lazy JSON key resolution
22+
jsonTag structtag.JSONTag // For JSON key resolution
2423
bundleTag structtag.BundleTag
2524
key string // Computed key (JSON key for structs, string key for maps, or Go field name for fallback)
2625
// If index >= 0, the node specifies a slice/array index in index.
@@ -74,23 +73,10 @@ func (p *PathNode) AnyIndex() bool {
7473
return p.index == tagAnyIndex
7574
}
7675

77-
func (p *PathNode) resolveField() {
78-
if p.index == tagUnresolvedStruct {
79-
// Lazy resolve JSON key for struct fields
80-
jsonName := p.jsonTag.Name()
81-
if jsonName != "" {
82-
p.key = jsonName
83-
}
84-
// If jsonName is empty, key already contains the Go field name as fallback
85-
p.index = tagStruct
86-
}
87-
}
88-
8976
func (p *PathNode) Field() (string, bool) {
9077
if p == nil {
9178
return "", false
9279
}
93-
p.resolveField()
9480
if p.index == tagStruct {
9581
return p.key, true
9682
}
@@ -125,17 +111,22 @@ func NewMapKey(prev *PathNode, key string) *PathNode {
125111
}
126112

127113
// NewStructField creates a new PathNode for a struct field.
128-
// The jsonTag is used for lazy JSON key resolution, and fieldName is used as fallback.
114+
// The jsonTag is used for JSON key resolution, and fieldName is used as fallback.
129115
func NewStructField(prev *PathNode, tag reflect.StructTag, fieldName string) *PathNode {
130116
jsonTag := structtag.JSONTag(tag.Get("json"))
131117
bundleTag := structtag.BundleTag(tag.Get("bundle"))
132118

119+
key := fieldName
120+
if name := jsonTag.Name(); name != "" {
121+
key = name
122+
}
123+
133124
return &PathNode{
134125
prev: prev,
135126
jsonTag: jsonTag,
136127
bundleTag: bundleTag,
137-
key: fieldName,
138-
index: tagUnresolvedStruct,
128+
key: key,
129+
index: tagStruct,
139130
}
140131
}
141132

@@ -167,8 +158,6 @@ func (p *PathNode) String() string {
167158
return p.prev.String() + "[*]"
168159
}
169160

170-
p.resolveField()
171-
172161
if p.index == tagStruct {
173162
return p.prev.String() + "." + p.key
174163
}
@@ -199,8 +188,6 @@ func (p *PathNode) DynPath() string {
199188
return p.prev.DynPath() + "[*]"
200189
}
201190

202-
p.resolveField()
203-
204191
prev := p.prev.DynPath()
205192
if prev == "" {
206193
return p.key

0 commit comments

Comments
 (0)