2025-10-15 10:12:44 +03:00

53 lines
1.3 KiB
Go

package core
import "strings"
type Pattern struct {
Text string
StarIndex int // -1 for exact match
}
func TryParsePattern(pattern string) Pattern {
starIndex := strings.Index(pattern, "*")
if starIndex == -1 || !strings.Contains(pattern[starIndex+1:], "*") {
return Pattern{Text: pattern, StarIndex: starIndex}
}
return Pattern{}
}
func (p *Pattern) IsValid() bool {
return p.StarIndex == -1 || p.StarIndex < len(p.Text)
}
func (p *Pattern) Matches(candidate string) bool {
if p.StarIndex == -1 {
return p.Text == candidate
}
return len(candidate) >= p.StarIndex &&
strings.HasPrefix(candidate, p.Text[:p.StarIndex]) &&
strings.HasSuffix(candidate, p.Text[p.StarIndex+1:])
}
func (p *Pattern) MatchedText(candidate string) string {
if !p.Matches(candidate) {
panic("candidate does not match pattern")
}
if p.StarIndex == -1 {
return ""
}
return candidate[p.StarIndex : len(candidate)-len(p.Text)+p.StarIndex+1]
}
func FindBestPatternMatch[T any](values []T, getPattern func(v T) Pattern, candidate string) T {
var bestPattern T
longestMatchPrefixLength := -1
for _, value := range values {
pattern := getPattern(value)
if (pattern.StarIndex == -1 || pattern.StarIndex > longestMatchPrefixLength) && pattern.Matches(candidate) {
bestPattern = value
longestMatchPrefixLength = pattern.StarIndex
}
}
return bestPattern
}