/
mod_path.go
121 lines (103 loc) · 2.4 KB
/
mod_path.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
package resources
import (
"encoding/json"
"fmt"
"strings"
)
type ResourceMod interface {
Apply(Resource) error
}
type ResourceModWithMultiple interface {
ApplyFromMultiple(Resource, map[FieldCopyModSource]Resource) error
}
type Path []*PathPart
type PathPart struct {
MapKey *string
ArrayIndex *PathPartArrayIndex
}
var _ json.Unmarshaler = &PathPart{}
type PathPartArrayIndex struct {
Index *int
All *bool `json:"allIndexes"`
}
func NewPathFromStrings(strs []string) Path {
var path Path
for _, str := range strs {
path = append(path, NewPathPartFromString(str))
}
return path
}
func NewPathFromInterfaces(parts []interface{}) Path {
var path Path
for _, part := range parts {
switch typedPart := part.(type) {
case string:
path = append(path, NewPathPartFromString(typedPart))
case int:
path = append(path, NewPathPartFromIndex(typedPart))
default:
panic(fmt.Sprintf("Unexpected part type %T", typedPart))
}
}
return path
}
func (p Path) AsStrings() []string {
var result []string
for _, part := range p {
if part.MapKey == nil {
panic(fmt.Sprintf("Unexpected non-map-key path part '%#v'", part))
}
result = append(result, *part.MapKey)
}
return result
}
func (p Path) AsString() string {
var result []string
for _, part := range p {
result = append(result, part.AsString())
}
return strings.Join(result, ",")
}
func (p Path) ContainsNonMapKeys() bool {
for _, part := range p {
if part.MapKey == nil {
return true
}
}
return false
}
func NewPathPartFromString(str string) *PathPart {
return &PathPart{MapKey: &str}
}
func NewPathPartFromIndex(i int) *PathPart {
return &PathPart{ArrayIndex: &PathPartArrayIndex{Index: &i}}
}
func NewPathPartFromIndexAll() *PathPart {
trueBool := true
return &PathPart{ArrayIndex: &PathPartArrayIndex{All: &trueBool}}
}
func (p *PathPart) AsString() string {
switch {
case p.MapKey != nil:
return *p.MapKey
case p.ArrayIndex != nil && p.ArrayIndex.Index != nil:
return fmt.Sprintf("%d", *p.ArrayIndex.Index)
case p.ArrayIndex != nil && p.ArrayIndex.All != nil:
return "(all)"
default:
panic("Unknown path part")
}
}
func (p *PathPart) UnmarshalJSON(data []byte) error {
var str string
var idx PathPartArrayIndex
switch {
case json.Unmarshal(data, &str) == nil:
p.MapKey = &str
case json.Unmarshal(data, &idx) == nil:
p.ArrayIndex = &idx
default:
return fmt.Errorf("Unknown path part")
}
return nil
}