...
1 package datasource
2
3 import (
4 "errors"
5 "strings"
6
7 "github.com/launchdarkly/go-server-sdk/v6/internal/datakinds"
8 "github.com/launchdarkly/go-server-sdk/v6/subsystems/ldstoretypes"
9
10 "github.com/launchdarkly/go-jsonstream/v3/jreader"
11 )
12
13 var (
14 putDataRequiredProperties = []string{"data"}
15 patchDataRequiredProperties = []string{"path", "data"}
16 deleteDataRequiredProperties = []string{"path", "version"}
17 )
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 type putData struct {
41 Path string
42 Data []ldstoretypes.Collection
43 }
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 type patchData struct {
60 Kind ldstoretypes.DataKind
61 Key string
62 Data ldstoretypes.ItemDescriptor
63 }
64
65
66
67
68
69
70
71
72
73
74
75 type deleteData struct {
76 Kind ldstoretypes.DataKind
77 Key string
78 Version int
79 }
80
81 func parsePutData(data []byte) (putData, error) {
82 var ret putData
83 r := jreader.NewReader(data)
84 for obj := r.Object().WithRequiredProperties(putDataRequiredProperties); obj.Next(); {
85 switch string(obj.Name()) {
86 case "path":
87 ret.Path = r.String()
88 case "data":
89 ret.Data = parseAllStoreDataFromJSONReader(&r)
90 }
91 }
92 return ret, r.Error()
93 }
94
95 func parsePatchData(data []byte) (patchData, error) {
96 var ret patchData
97 r := jreader.NewReader(data)
98 var kind datakinds.DataKindInternal
99 var key string
100 parseItem := func() (patchData, error) {
101 item, err := kind.DeserializeFromJSONReader(&r)
102 if err != nil {
103 return patchData{}, err
104 }
105 ret.Data = item
106 return ret, nil
107 }
108 for obj := r.Object().WithRequiredProperties(patchDataRequiredProperties); obj.Next(); {
109 switch string(obj.Name()) {
110 case "path":
111 path := r.String()
112 kind, key = parsePath(path)
113 ret.Kind, ret.Key = kind, key
114 if kind == nil {
115
116
117 return ret, nil
118 }
119 case "data":
120 if kind != nil {
121
122
123
124 return parseItem()
125 }
126 }
127 }
128 if err := r.Error(); err != nil {
129 return patchData{}, err
130 }
131
132
133
134 r = jreader.NewReader(data)
135 for obj := r.Object(); obj.Next(); {
136 if string(obj.Name()) == "data" {
137 return parseItem()
138 }
139 }
140 if r.Error() != nil {
141 return patchData{}, r.Error()
142 }
143 return patchData{}, errors.New("patch event had no data property")
144 }
145
146 func parseDeleteData(data []byte) (deleteData, error) {
147 var ret deleteData
148 r := jreader.NewReader(data)
149 for obj := r.Object().WithRequiredProperties(deleteDataRequiredProperties); obj.Next(); {
150 switch string(obj.Name()) {
151 case "path":
152 path := r.String()
153 ret.Kind, ret.Key = parsePath(path)
154 if ret.Kind == nil {
155
156
157 return ret, nil
158 }
159 case "version":
160 ret.Version = r.Int()
161 }
162 }
163 if r.Error() != nil {
164 return deleteData{}, r.Error()
165 }
166 return ret, nil
167 }
168
169 func parsePath(path string) (datakinds.DataKindInternal, string) {
170 switch {
171 case strings.HasPrefix(path, "/segments/"):
172 return datakinds.Segments, strings.TrimPrefix(path, "/segments/")
173 case strings.HasPrefix(path, "/flags/"):
174 return datakinds.Features, strings.TrimPrefix(path, "/flags/")
175 default:
176 return nil, ""
177 }
178 }
179
View as plain text