type StringMatcher interface {
Match(input string) bool
String() string
+ Sub(vars map[string]string) StringMatcher
}
type Prefix string
type Any struct{}
type Never struct{}
+type MatchableString interface {
+ ~string
+ StringMatcher
+}
+
+func sub[T MatchableString](inp T, vars map[string]string) StringMatcher {
+ out := string(inp)
+ for name, value := range vars {
+ out = strings.ReplaceAll(out, "{{"+name+"}}", value)
+ }
+ return T(out)
+}
+
func (s Prefix) Match(input string) bool {
return strings.HasPrefix(input, string(s))
}
return fmt.Sprintf("%T(%s)", s, string(s))
}
+func (s Prefix) Sub(vars map[string]string) StringMatcher {
+ return sub(s, vars)
+}
+
func (s Suffix) Match(input string) bool {
return strings.HasSuffix(input, string(s))
}
return fmt.Sprintf("%T(%s)", s, string(s))
}
+func (s Suffix) Sub(vars map[string]string) StringMatcher {
+ return sub(s, vars)
+}
+
func (s Exact) Match(input string) bool {
return input == string(s)
}
return fmt.Sprintf("%T(%s)", s, string(s))
}
+func (s Exact) Sub(vars map[string]string) StringMatcher {
+ return sub(s, vars)
+}
+
func (s Contains) Match(input string) bool {
return strings.Contains(input, string(s))
}
return fmt.Sprintf("%T(%s)", s, string(s))
}
+func (s Contains) Sub(vars map[string]string) StringMatcher {
+ return sub(s, vars)
+}
+
func (s Regexp) Match(input string) bool {
re := regexp.MustCompile(string(s))
return re.MatchString(input)
return fmt.Sprintf("%T(%s)", s, string(s))
}
+func (s Regexp) Sub(vars map[string]string) StringMatcher {
+ return sub(s, vars)
+}
+
func (s Any) String() string {
return fmt.Sprintf("%T", s)
}
return true
}
+func (s Any) Sub(vars map[string]string) StringMatcher {
+ return s
+}
+
func (s Never) Match(string) bool {
return false
}
return fmt.Sprintf("%T", s)
}
+func (s Never) Sub(vars map[string]string) StringMatcher {
+ return s
+}
+
type andMatcher struct {
matchers []StringMatcher
}
return fmt.Sprintf("And(%s)", strings.Join(matcherStrs, " & "))
}
+func (mm *andMatcher) Sub(vars map[string]string) StringMatcher {
+ dup := &andMatcher{}
+ for _, m := range mm.matchers {
+ dup.matchers = append(dup.matchers, m.Sub(vars))
+ }
+ return dup
+}
+
func And(matchers ...StringMatcher) StringMatcher {
return &andMatcher{
matchers: matchers,
return fmt.Sprintf("Or(%s)", strings.Join(matcherStrs, " & "))
}
+func (mm *orMatcher) Sub(vars map[string]string) StringMatcher {
+ dup := &andMatcher{}
+ for _, m := range mm.matchers {
+ dup.matchers = append(dup.matchers, m.Sub(vars))
+ }
+ return dup
+}
+
func Or(matchers ...StringMatcher) StringMatcher {
return &orMatcher{
matchers: matchers,