forked from mirror/glob
103 lines
1.6 KiB
Go
103 lines
1.6 KiB
Go
package match
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type Kind int
|
|
|
|
// todo use String for Kind, and self.Kind() in every matcher.String()
|
|
const (
|
|
KindRaw Kind = iota
|
|
KindEveryOf
|
|
KindAnyOf
|
|
KindAny
|
|
KindSuper
|
|
KindSingle
|
|
KindComposition
|
|
KindPrefix
|
|
KindSuffix
|
|
KindPrefixSuffix
|
|
KindRange
|
|
KindList
|
|
KindMin
|
|
KindMax
|
|
KindBTree
|
|
KindContains
|
|
)
|
|
|
|
type Matcher interface {
|
|
Match(string) bool
|
|
Index(string) (int, []int)
|
|
Len() int
|
|
}
|
|
|
|
type Matchers []Matcher
|
|
|
|
func (m Matchers) String() string {
|
|
var s []string
|
|
for _, matcher := range m {
|
|
s = append(s, fmt.Sprint(matcher))
|
|
}
|
|
|
|
return fmt.Sprintf("matchers[%s]", strings.Join(s, ","))
|
|
}
|
|
|
|
func appendIfNotAsPrevious(target []int, val int) []int {
|
|
l := len(target)
|
|
if l != 0 && target[l-1] == val {
|
|
return target
|
|
}
|
|
|
|
return append(target, val)
|
|
}
|
|
|
|
// mergeSegments merges and sorts given already SORTED and UNIQUE segments.
|
|
func mergeSegments(segments [][]int) []int {
|
|
var current []int
|
|
for _, s := range segments {
|
|
if current == nil {
|
|
current = s
|
|
continue
|
|
}
|
|
|
|
var next []int
|
|
for x, y := 0, 0; x < len(current) || y < len(s); {
|
|
if x >= len(current) {
|
|
next = append(next, s[y:]...)
|
|
break
|
|
}
|
|
|
|
if y >= len(s) {
|
|
next = append(next, current[x:]...)
|
|
break
|
|
}
|
|
|
|
xValue := current[x]
|
|
yValue := s[y]
|
|
|
|
switch {
|
|
|
|
case xValue == yValue:
|
|
x++
|
|
y++
|
|
next = appendIfNotAsPrevious(next, xValue)
|
|
|
|
case xValue < yValue:
|
|
next = appendIfNotAsPrevious(next, xValue)
|
|
x++
|
|
|
|
case yValue < xValue:
|
|
next = appendIfNotAsPrevious(next, yValue)
|
|
y++
|
|
|
|
}
|
|
}
|
|
|
|
current = next
|
|
}
|
|
|
|
return current
|
|
}
|