glob/match/match.go

130 lines
1.9 KiB
Go
Raw Normal View History

2015-12-24 17:54:54 +03:00
package match
2016-02-23 14:46:20 +03:00
// todo common table of rune's length
2016-01-08 20:14:31 +03:00
import (
"fmt"
"strings"
)
2015-12-24 17:54:54 +03:00
type Matcher interface {
Match(string) bool
2018-02-16 17:36:02 +03:00
MinLen() int
}
type Indexer interface {
2016-02-05 17:29:41 +03:00
Index(string) (int, []int)
2018-02-16 17:36:02 +03:00
}
type Sizer interface {
RunesCount() int
}
type MatchIndexer interface {
Matcher
Indexer
}
type MatchSizer interface {
Matcher
Sizer
}
type MatchIndexSizer interface {
Matcher
Indexer
Sizer
}
type Container interface {
2019-02-06 23:43:38 +03:00
Content(func(Matcher))
2018-02-16 17:36:02 +03:00
}
func MatchIndexers(ms []Matcher) ([]MatchIndexer, bool) {
for _, m := range ms {
2018-11-24 21:47:12 +03:00
if _, ok := m.(MatchIndexer); !ok {
2018-02-16 17:36:02 +03:00
return nil, false
}
}
2018-11-24 21:47:12 +03:00
r := make([]MatchIndexer, len(ms))
for i := range r {
r[i] = ms[i].(MatchIndexer)
2018-02-16 17:36:02 +03:00
}
2018-11-24 21:47:12 +03:00
return r, true
}
func MatchIndexSizers(ms []Matcher) ([]MatchIndexSizer, bool) {
for _, m := range ms {
if _, ok := m.(MatchIndexSizer); !ok {
return nil, false
}
}
r := make([]MatchIndexSizer, len(ms))
for i := range r {
r[i] = ms[i].(MatchIndexSizer)
}
return r, true
2016-01-08 20:14:31 +03:00
}
type Matchers []Matcher
func (m Matchers) String() string {
var s []string
for _, matcher := range m {
s = append(s, fmt.Sprint(matcher))
}
2016-01-13 01:26:48 +03:00
return fmt.Sprintf("%s", strings.Join(s, ","))
2016-01-08 20:14:31 +03:00
}
2016-01-12 14:06:59 +03:00
2016-02-02 22:20:26 +03:00
// appendMerge merges and sorts given already SORTED and UNIQUE segments.
2016-02-02 22:03:37 +03:00
func appendMerge(target, sub []int) []int {
lt, ls := len(target), len(sub)
2016-02-05 16:57:42 +03:00
out := make([]int, 0, lt+ls)
2016-02-02 22:03:37 +03:00
for x, y := 0, 0; x < lt || y < ls; {
if x >= lt {
out = append(out, sub[y:]...)
break
}
if y >= ls {
out = append(out, target[x:]...)
break
}
xValue := target[x]
yValue := sub[y]
switch {
case xValue == yValue:
out = append(out, xValue)
x++
y++
case xValue < yValue:
out = append(out, xValue)
x++
case yValue < xValue:
out = append(out, yValue)
y++
}
}
target = append(target[:0], out...)
return target
}
func reverseSegments(input []int) {
l := len(input)
m := l / 2
for i := 0; i < m; i++ {
input[i], input[l-i-1] = input[l-i-1], input[i]
}
2016-01-12 14:06:59 +03:00
}