-
Notifications
You must be signed in to change notification settings - Fork 85
/
patch_struct.go
66 lines (54 loc) · 1.51 KB
/
patch_struct.go
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
package diff
import "reflect"
/**
Types are being split out to more closely follow the library structure already
in place. Keeps the file simpler as well.
*/
type structField struct {
f reflect.StructField
v reflect.Value
}
func getNestedFields(v reflect.Value, flattenEmbedded bool) []structField {
fields := make([]structField, 0)
for i := 0; i < v.NumField(); i++ {
f := v.Type().Field(i)
fv := v.Field(i)
if fv.Kind() == reflect.Struct && f.Anonymous && flattenEmbedded {
fields = append(fields, getNestedFields(fv, flattenEmbedded)...)
} else {
fields = append(fields, structField{f, fv})
}
}
return fields
}
//patchStruct - handles the rendering of a struct field
func (d *Differ) patchStruct(c *ChangeValue) {
field := c.change.Path[c.pos]
structFields := getNestedFields(*c.target, d.FlattenEmbeddedStructs)
for _, structField := range structFields {
f := structField.f
tname := tagName(d.TagName, f)
if tname == "-" {
continue
}
if tname == field || f.Name == field {
x := structField.v
if hasTagOption(d.TagName, f, "nocreate") {
c.SetFlag(OptionNoCreate)
}
if hasTagOption(d.TagName, f, "omitunequal") {
c.SetFlag(OptionOmitUnequal)
}
if hasTagOption(d.TagName, f, "immutable") {
c.SetFlag(OptionImmutable)
}
c.swap(&x)
break
}
}
}
//track and zero out struct members
func (d *Differ) deleteStructEntry(c *ChangeValue) {
//deleting a struct value set's it to the 'basic' type
c.Set(reflect.Zero(c.target.Type()), d.ConvertCompatibleTypes)
}