53 lines
1.3 KiB
Go
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
|
|
}
|