Marshal Matcher to JSON for API v1 compatibility
Signed-off-by: Kiril Vladimirov <kiril@vladimiroff.org>
This commit is contained in:
parent
97e0c754c0
commit
f85651f2c4
|
@ -15,6 +15,7 @@ package labels
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
@ -91,6 +92,49 @@ func (m *Matcher) Matches(s string) bool {
|
|||
panic("labels.Matcher.Matches: invalid match type")
|
||||
}
|
||||
|
||||
type apiV1Matcher struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
IsRegex bool `json:"isRegex"`
|
||||
IsEqual bool `json:"isEqual"`
|
||||
}
|
||||
|
||||
// MarshalJSON retains backwards compatibility with types.Matcher for the v1 API.
|
||||
func (m Matcher) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(apiV1Matcher{
|
||||
Name: m.Name,
|
||||
Value: m.Value,
|
||||
IsRegex: m.Type == MatchRegexp || m.Type == MatchNotRegexp,
|
||||
IsEqual: m.Type == MatchRegexp || m.Type == MatchEqual,
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Matcher) UnmarshalJSON(data []byte) error {
|
||||
var v1m apiV1Matcher
|
||||
if err := json.Unmarshal(data, &v1m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var t MatchType
|
||||
switch {
|
||||
case v1m.IsEqual && !v1m.IsRegex:
|
||||
t = MatchEqual
|
||||
case !v1m.IsEqual && !v1m.IsRegex:
|
||||
t = MatchNotEqual
|
||||
case v1m.IsEqual && v1m.IsRegex:
|
||||
t = MatchRegexp
|
||||
case !v1m.IsEqual && v1m.IsRegex:
|
||||
t = MatchNotRegexp
|
||||
}
|
||||
|
||||
matcher, err := NewMatcher(t, v1m.Name, v1m.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = *matcher
|
||||
return nil
|
||||
}
|
||||
|
||||
// openMetricsEscape is similar to the usual string escaping, but more
|
||||
// restricted. It merely replaces a new-line character with '\n', a double-quote
|
||||
// character with '\"', and a backslash with '\\', which is the escaping used by
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
|
||||
package labels
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func mustNewMatcher(t *testing.T, mType MatchType, value string) *Matcher {
|
||||
m, err := NewMatcher(mType, "", value)
|
||||
|
@ -191,3 +194,64 @@ line`,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatcherJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
op MatchType
|
||||
value string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: `foo`,
|
||||
op: MatchEqual,
|
||||
value: `bar`,
|
||||
want: `{"name":"foo","value":"bar","isRegex":false,"isEqual":true}`,
|
||||
},
|
||||
{
|
||||
name: `foo`,
|
||||
op: MatchNotEqual,
|
||||
value: `bar`,
|
||||
want: `{"name":"foo","value":"bar","isRegex":false,"isEqual":false}`,
|
||||
},
|
||||
{
|
||||
name: `foo`,
|
||||
op: MatchRegexp,
|
||||
value: `bar`,
|
||||
want: `{"name":"foo","value":"bar","isRegex":true,"isEqual":true}`,
|
||||
},
|
||||
{
|
||||
name: `foo`,
|
||||
op: MatchNotRegexp,
|
||||
value: `bar`,
|
||||
want: `{"name":"foo","value":"bar","isRegex":true,"isEqual":false}`,
|
||||
},
|
||||
}
|
||||
|
||||
cmp := func(m1, m2 Matcher) bool {
|
||||
return m1.Name == m2.Name && m1.Value == m2.Value && m1.Type == m2.Type
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
m, err := NewMatcher(test.op, test.name, test.value)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := string(b); got != test.want {
|
||||
t.Errorf("Unexpected JSON representation of matcher:\nwant:\t%v\ngot:\t%v", test.want, got)
|
||||
}
|
||||
|
||||
var m2 Matcher
|
||||
if err := json.Unmarshal(b, &m2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !cmp(*m, m2) {
|
||||
t.Errorf("Doing Marshal and Unmarshal seems to be losing data; before %#v, after %#v", m, m2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue