github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/scrape/labels/matcher.go (about) 1 // Copyright 2017 The Prometheus Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package labels 15 16 import ( 17 "fmt" 18 ) 19 20 // MatchType is an enum for label matching types. 21 type MatchType int 22 23 // Possible MatchTypes. 24 const ( 25 MatchEqual MatchType = iota 26 MatchNotEqual 27 MatchRegexp 28 MatchNotRegexp 29 ) 30 31 var matchTypeToStr = [...]string{ 32 MatchEqual: "=", 33 MatchNotEqual: "!=", 34 MatchRegexp: "=~", 35 MatchNotRegexp: "!~", 36 } 37 38 func (m MatchType) String() string { 39 if m < MatchEqual || m > MatchNotRegexp { 40 panic("unknown match type") 41 } 42 return matchTypeToStr[m] 43 } 44 45 // Matcher models the matching of a label. 46 type Matcher struct { 47 Type MatchType 48 Name string 49 Value string 50 51 re *FastRegexMatcher 52 } 53 54 // NewMatcher returns a matcher object. 55 func NewMatcher(t MatchType, n, v string) (*Matcher, error) { 56 m := &Matcher{ 57 Type: t, 58 Name: n, 59 Value: v, 60 } 61 if t == MatchRegexp || t == MatchNotRegexp { 62 re, err := NewFastRegexMatcher(v) 63 if err != nil { 64 return nil, err 65 } 66 m.re = re 67 } 68 return m, nil 69 } 70 71 // MustNewMatcher panics on error - only for use in tests! 72 func MustNewMatcher(mt MatchType, name, val string) *Matcher { 73 m, err := NewMatcher(mt, name, val) 74 if err != nil { 75 panic(err) 76 } 77 return m 78 } 79 80 func (m *Matcher) String() string { 81 return fmt.Sprintf("%s%s%q", m.Name, m.Type, m.Value) 82 } 83 84 // Matches returns whether the matcher matches the given string value. 85 func (m *Matcher) Matches(s string) bool { 86 switch m.Type { 87 case MatchEqual: 88 return s == m.Value 89 case MatchNotEqual: 90 return s != m.Value 91 case MatchRegexp: 92 return m.re.MatchString(s) 93 case MatchNotRegexp: 94 return !m.re.MatchString(s) 95 } 96 panic("labels.Matcher.Matches: invalid match type") 97 } 98 99 // Inverse returns a matcher that matches the opposite. 100 func (m *Matcher) Inverse() (*Matcher, error) { 101 switch m.Type { 102 case MatchEqual: 103 return NewMatcher(MatchNotEqual, m.Name, m.Value) 104 case MatchNotEqual: 105 return NewMatcher(MatchEqual, m.Name, m.Value) 106 case MatchRegexp: 107 return NewMatcher(MatchNotRegexp, m.Name, m.Value) 108 case MatchNotRegexp: 109 return NewMatcher(MatchRegexp, m.Name, m.Value) 110 } 111 panic("labels.Matcher.Matches: invalid match type") 112 } 113 114 // GetRegexString returns the regex string. 115 func (m *Matcher) GetRegexString() string { 116 if m.re == nil { 117 return "" 118 } 119 return m.re.GetRegexString() 120 }