-
Notifications
You must be signed in to change notification settings - Fork 100
/
map.go
108 lines (94 loc) · 2.29 KB
/
map.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
package data
import (
"slices"
"strings"
v1common "go.opentelemetry.io/proto/otlp/common/v1"
"google.golang.org/protobuf/proto"
)
type Map struct {
raw *[]*v1common.KeyValue
}
func NewMap(opts ...func(Map)) Map {
m := Map{
raw: new([]*v1common.KeyValue),
}
for _, opt := range opts {
opt(m)
}
return m
}
// WithDelimtedStrings splits each value based on the delim passed,
// if there is no delim present, then the entire string is added to the key
// and uses an empty string as the value
func WithDelimitedStrings[Tags ~[]string](delim string, tags Tags) func(m Map) {
return func(m Map) {
for _, kv := range tags {
idx := strings.Index(kv, delim)
switch idx {
case -1:
// No delimiter found
m.Insert(kv, "")
default:
m.Insert(kv[:idx], kv[idx+1:])
}
}
}
}
func WithStatsdDelimitedTags[Tags ~[]string](tags Tags) func(Map) {
return WithDelimitedStrings(":", tags)
}
func (m Map) Equal(mm Map) bool {
return proto.Equal(
&v1common.KeyValueList{Values: *m.raw},
&v1common.KeyValueList{Values: *mm.raw},
)
}
func (m Map) Insert(key string, value string) {
index := slices.IndexFunc(*m.raw, func(kv *v1common.KeyValue) bool {
return kv.Key == key
})
val := &v1common.AnyValue{
Value: &v1common.AnyValue_StringValue{
StringValue: value,
},
}
switch index {
case -1:
// The value doesn't exist within the map, appending to end
*m.raw = append(*m.raw, &v1common.KeyValue{
Key: key,
Value: val,
})
default:
if v, ok := (*m.raw)[index].Value.Value.(*v1common.AnyValue_StringValue); ok && v.StringValue == value {
return
}
v, ok := (*m.raw)[index].Value.Value.(*v1common.AnyValue_ArrayValue)
if !ok {
// Convert a simple key value into an array of values
v = &v1common.AnyValue_ArrayValue{
ArrayValue: &v1common.ArrayValue{
Values: []*v1common.AnyValue{
{Value: v},
},
},
}
}
v.ArrayValue.Values = append(v.ArrayValue.Values, val)
}
}
func (m Map) Merge(mm Map) {
for _, kv := range *mm.raw {
switch v := kv.Value.Value.(type) {
case *v1common.AnyValue_StringValue:
m.Insert(kv.Key, v.StringValue)
case *v1common.AnyValue_ArrayValue:
for _, vv := range v.ArrayValue.Values {
m.Insert(kv.Key, vv.GetStringValue())
}
}
}
}
func (m Map) unwrap() []*v1common.KeyValue {
return *m.raw
}