...
1
16
17 package internal
18
19 import (
20 "encoding/json"
21 "errors"
22 "fmt"
23 "strconv"
24 "strings"
25
26 "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
27 "sigs.k8s.io/structured-merge-diff/v4/value"
28 )
29
30 const (
31
32 Field = "f"
33
34
35 Value = "v"
36
37
38 Index = "i"
39
40
41 Key = "k"
42
43
44 Separator = ":"
45 )
46
47
48 func NewPathElement(s string) (fieldpath.PathElement, error) {
49 split := strings.SplitN(s, Separator, 2)
50 if len(split) < 2 {
51 return fieldpath.PathElement{}, fmt.Errorf("missing colon: %v", s)
52 }
53 switch split[0] {
54 case Field:
55 return fieldpath.PathElement{
56 FieldName: &split[1],
57 }, nil
58 case Value:
59 val, err := value.FromJSON([]byte(split[1]))
60 if err != nil {
61 return fieldpath.PathElement{}, err
62 }
63 return fieldpath.PathElement{
64 Value: &val,
65 }, nil
66 case Index:
67 i, err := strconv.Atoi(split[1])
68 if err != nil {
69 return fieldpath.PathElement{}, err
70 }
71 return fieldpath.PathElement{
72 Index: &i,
73 }, nil
74 case Key:
75 kv := map[string]json.RawMessage{}
76 err := json.Unmarshal([]byte(split[1]), &kv)
77 if err != nil {
78 return fieldpath.PathElement{}, err
79 }
80 fields := value.FieldList{}
81 for k, v := range kv {
82 b, err := json.Marshal(v)
83 if err != nil {
84 return fieldpath.PathElement{}, err
85 }
86 val, err := value.FromJSON(b)
87 if err != nil {
88 return fieldpath.PathElement{}, err
89 }
90
91 fields = append(fields, value.Field{
92 Name: k,
93 Value: val,
94 })
95 }
96 return fieldpath.PathElement{
97 Key: &fields,
98 }, nil
99 default:
100
101 return fieldpath.PathElement{}, nil
102 }
103 }
104
105
106 func PathElementString(pe fieldpath.PathElement) (string, error) {
107 switch {
108 case pe.FieldName != nil:
109 return Field + Separator + *pe.FieldName, nil
110 case pe.Key != nil:
111 kv := map[string]json.RawMessage{}
112 for _, k := range *pe.Key {
113 b, err := value.ToJSON(k.Value)
114 if err != nil {
115 return "", err
116 }
117 m := json.RawMessage{}
118 err = json.Unmarshal(b, &m)
119 if err != nil {
120 return "", err
121 }
122 kv[k.Name] = m
123 }
124 b, err := json.Marshal(kv)
125 if err != nil {
126 return "", err
127 }
128 return Key + ":" + string(b), nil
129 case pe.Value != nil:
130 b, err := value.ToJSON(*pe.Value)
131 if err != nil {
132 return "", err
133 }
134 return Value + ":" + string(b), nil
135 case pe.Index != nil:
136 return Index + ":" + strconv.Itoa(*pe.Index), nil
137 default:
138 return "", errors.New("Invalid type of path element")
139 }
140 }
141
View as plain text