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  }