64 lines
2.0 KiB
Go
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
|
|
}
|