/
utils.go
124 lines (108 loc) · 2.91 KB
/
utils.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
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
package runner
import (
"github.com/pkg/errors"
"github.com/spyzhov/ajson"
"golang.org/x/exp/slices"
)
func UpdateWithConfigurableDefinitions(original []byte, updateWith []byte, configurableDefinitions map[string]*ajson.Node) ([]byte, error) {
originalNode, err := ajson.Unmarshal(original)
if err != nil {
return nil, errors.Wrap(err, "error reading original schema")
}
updateWithNode, err := ajson.Unmarshal(updateWith)
if err != nil {
return nil, errors.Wrap(err, "error reading updatedWith schema")
}
originalNodeDefs, err := originalNode.GetKey("$defs")
if err != nil {
return nil, err
}
updateWithNodeDefs, err := updateWithNode.GetKey("$defs")
if err != nil {
return nil, err
}
keys := originalNodeDefs.Keys()
slices.Sort(keys)
for _, defKey := range keys {
v, err := originalNodeDefs.GetKey(defKey)
if err != nil {
return nil, errors.Wrapf(err, "unable to get original key: %s", defKey)
}
if v == nil {
continue
}
if r, ok := configurableDefinitions[defKey]; ok {
// replace this def with configurable one
// store important props before replace
configurable := getBool("configurable", v)
path := getStr("path", v)
propertyOrder := getInt("propertyOrder", v)
//
_ = setStr("path", path, r)
_ = setBool("configurable", configurable, r)
_ = setInt("propertyOrder", propertyOrder, r)
if err = v.SetNode(r); err != nil {
return nil, err
}
continue
}
if !getBool("configurable", v) {
continue
}
updated, err := updateWithNodeDefs.GetKey(defKey)
if updated == nil {
// in user's customised schema definition is not presented, skipping
continue
}
if err = v.SetNode(updated); err != nil {
return nil, err
}
configurableDefinitions[defKey] = updated
}
return ajson.Marshal(originalNode)
}
func setStr(param string, val string, v *ajson.Node) error {
if c, err := v.GetKey(param); err == nil {
return c.SetNode(ajson.StringNode("", val))
}
return v.AppendObject(param, ajson.StringNode("", val))
}
func setBool(param string, val bool, v *ajson.Node) error {
if c, err := v.GetKey(param); err == nil {
return c.SetNode(ajson.BoolNode("", val))
}
return v.AppendObject(param, ajson.BoolNode("", val))
}
func setInt(param string, val int, v *ajson.Node) error {
if c, err := v.GetKey(param); err == nil {
return c.SetNode(ajson.NumericNode("", float64(val)))
}
return v.AppendObject(param, ajson.NumericNode("", float64(val)))
}
func getStr(param string, v *ajson.Node) string {
c, _ := v.GetKey(param)
if c != nil {
// if node has override
b, _ := c.GetString()
return b
}
return ""
}
func getInt(param string, v *ajson.Node) int {
c, _ := v.GetKey(param)
if c != nil {
// if node has override
b, _ := c.GetNumeric()
return int(b)
}
return 0
}
func getBool(param string, v *ajson.Node) bool {
c, _ := v.GetKey(param)
if c != nil {
// if node has override
b, _ := c.GetBool()
return b
}
return false
}