Files
Cyrene_v2/internal/bus/match.go
T

64 lines
2.0 KiB
Go

package bus
import (
"fmt"
"strings"
)
// match reports whether subject matches pattern using the wildcard rules
// described in the package comment: "*" matches exactly one non-empty token,
// ">" matches one or more trailing tokens and must be the last token, and any
// other token matches an identical subject token. Callers must have validated
// both inputs, so an empty token or a misplaced ">" never reaches here.
func match(pattern, subject string) bool {
p := strings.Split(pattern, ".")
s := strings.Split(subject, ".")
i, j := 0, 0
for i < len(p) {
if p[i] == ">" {
// ">" is guaranteed to be the last token; it needs at least one
// remaining subject token.
return j < len(s)
}
if j >= len(s) {
return false
}
if p[i] != "*" && p[i] != s[j] {
return false
}
i++
j++
}
return j == len(s)
}
// validateSubject rejects an empty subject or one containing an empty token
// (leading/trailing/repeated dots).
func validateSubject(subject string) error {
if subject == "" {
return fmt.Errorf("bus: subject must not be empty: %w", ErrInvalidArgument)
}
if strings.HasPrefix(subject, ".") || strings.HasSuffix(subject, ".") || strings.Contains(subject, "..") {
return fmt.Errorf("bus: subject %q contains an empty token: %w", subject, ErrInvalidArgument)
}
return nil
}
// validatePattern rejects an empty pattern, one with an empty token, or one
// where the ">" wildcard is not the final token.
func validatePattern(pattern string) error {
if pattern == "" {
return fmt.Errorf("bus: pattern must not be empty: %w", ErrInvalidArgument)
}
if strings.HasPrefix(pattern, ".") || strings.HasSuffix(pattern, ".") || strings.Contains(pattern, "..") {
return fmt.Errorf("bus: pattern %q contains an empty token: %w", pattern, ErrInvalidArgument)
}
tokens := strings.Split(pattern, ".")
for i, tok := range tokens {
if tok == ">" && i != len(tokens)-1 {
return fmt.Errorf("bus: pattern %q: '>' wildcard must be the last token: %w", pattern, ErrInvalidArgument)
}
}
return nil
}