1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tag
17
18 import (
19 "bytes"
20 "context"
21 "fmt"
22 "sort"
23 )
24
25
26 type Tag struct {
27 Key Key
28 Value string
29 }
30
31 type tagContent struct {
32 value string
33 m metadatas
34 }
35
36
37
38 type Map struct {
39 m map[Key]tagContent
40 }
41
42
43 func (m *Map) Value(k Key) (string, bool) {
44 if m == nil {
45 return "", false
46 }
47 v, ok := m.m[k]
48 return v.value, ok
49 }
50
51 func (m *Map) String() string {
52 if m == nil {
53 return "nil"
54 }
55 keys := make([]Key, 0, len(m.m))
56 for k := range m.m {
57 keys = append(keys, k)
58 }
59 sort.Slice(keys, func(i, j int) bool { return keys[i].Name() < keys[j].Name() })
60
61 var buffer bytes.Buffer
62 buffer.WriteString("{ ")
63 for _, k := range keys {
64 buffer.WriteString(fmt.Sprintf("{%v %v}", k.name, m.m[k]))
65 }
66 buffer.WriteString(" }")
67 return buffer.String()
68 }
69
70 func (m *Map) insert(k Key, v string, md metadatas) {
71 if _, ok := m.m[k]; ok {
72 return
73 }
74 m.m[k] = tagContent{value: v, m: md}
75 }
76
77 func (m *Map) update(k Key, v string, md metadatas) {
78 if _, ok := m.m[k]; ok {
79 m.m[k] = tagContent{value: v, m: md}
80 }
81 }
82
83 func (m *Map) upsert(k Key, v string, md metadatas) {
84 m.m[k] = tagContent{value: v, m: md}
85 }
86
87 func (m *Map) delete(k Key) {
88 delete(m.m, k)
89 }
90
91 func newMap() *Map {
92 return &Map{m: make(map[Key]tagContent)}
93 }
94
95
96 type Mutator interface {
97 Mutate(t *Map) (*Map, error)
98 }
99
100
101
102
103
104
105
106
107 func Insert(k Key, v string, mds ...Metadata) Mutator {
108 return &mutator{
109 fn: func(m *Map) (*Map, error) {
110 if !checkValue(v) {
111 return nil, errInvalidValue
112 }
113 m.insert(k, v, createMetadatas(mds...))
114 return m, nil
115 },
116 }
117 }
118
119
120
121
122
123
124
125
126 func Update(k Key, v string, mds ...Metadata) Mutator {
127 return &mutator{
128 fn: func(m *Map) (*Map, error) {
129 if !checkValue(v) {
130 return nil, errInvalidValue
131 }
132 m.update(k, v, createMetadatas(mds...))
133 return m, nil
134 },
135 }
136 }
137
138
139
140
141
142
143
144
145
146 func Upsert(k Key, v string, mds ...Metadata) Mutator {
147 return &mutator{
148 fn: func(m *Map) (*Map, error) {
149 if !checkValue(v) {
150 return nil, errInvalidValue
151 }
152 m.upsert(k, v, createMetadatas(mds...))
153 return m, nil
154 },
155 }
156 }
157
158 func createMetadatas(mds ...Metadata) metadatas {
159 var metas metadatas
160 if len(mds) > 0 {
161 for _, md := range mds {
162 if md != nil {
163 md(&metas)
164 }
165 }
166 } else {
167 WithTTL(TTLUnlimitedPropagation)(&metas)
168 }
169 return metas
170
171 }
172
173
174
175 func Delete(k Key) Mutator {
176 return &mutator{
177 fn: func(m *Map) (*Map, error) {
178 m.delete(k)
179 return m, nil
180 },
181 }
182 }
183
184
185
186
187 func New(ctx context.Context, mutator ...Mutator) (context.Context, error) {
188 m := newMap()
189 orig := FromContext(ctx)
190 if orig != nil {
191 for k, v := range orig.m {
192 if !checkKeyName(k.Name()) {
193 return ctx, fmt.Errorf("key:%q: %v", k, errInvalidKeyName)
194 }
195 if !checkValue(v.value) {
196 return ctx, fmt.Errorf("key:%q value:%q: %v", k.Name(), v, errInvalidValue)
197 }
198 m.insert(k, v.value, v.m)
199 }
200 }
201 var err error
202 for _, mod := range mutator {
203 m, err = mod.Mutate(m)
204 if err != nil {
205 return ctx, err
206 }
207 }
208 return NewContext(ctx, m), nil
209 }
210
211
212
213
214
215
216
217
218
219 func Do(ctx context.Context, f func(ctx context.Context)) {
220 do(ctx, f)
221 }
222
223 type mutator struct {
224 fn func(t *Map) (*Map, error)
225 }
226
227 func (m *mutator) Mutate(t *Map) (*Map, error) {
228 return m.fn(t)
229 }
230
View as plain text