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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -91,6 +92,49 @@ func (m *Matcher) Matches(s string) bool {
|
||||||
panic("labels.Matcher.Matches: invalid match type")
|
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
|
// openMetricsEscape is similar to the usual string escaping, but more
|
||||||
// restricted. It merely replaces a new-line character with '\n', a double-quote
|
// 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
|
// character with '\"', and a backslash with '\\', which is the escaping used by
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
|
|
||||||
package labels
|
package labels
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func mustNewMatcher(t *testing.T, mType MatchType, value string) *Matcher {
|
func mustNewMatcher(t *testing.T, mType MatchType, value string) *Matcher {
|
||||||
m, err := NewMatcher(mType, "", value)
|
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