glob/match/row.go

91 lines
1.5 KiB
Go
Raw Permalink Normal View History

2016-01-09 02:34:41 +03:00
package match
import (
"fmt"
2018-02-16 17:36:02 +03:00
"unicode/utf8"
2019-02-06 23:43:38 +03:00
"github.com/gobwas/glob/internal/debug"
2018-02-16 17:36:02 +03:00
"github.com/gobwas/glob/util/runes"
2016-01-09 02:34:41 +03:00
)
type Row struct {
2018-02-16 17:36:02 +03:00
ms []MatchIndexSizer
runes int
seg []int
2016-02-23 14:46:20 +03:00
}
2018-02-16 17:36:02 +03:00
func NewRow(ms []MatchIndexSizer) Row {
var r int
for _, m := range ms {
r += m.RunesCount()
}
2016-02-23 14:46:20 +03:00
return Row{
2018-02-16 17:36:02 +03:00
ms: ms,
runes: r,
seg: []int{r},
2016-02-23 14:46:20 +03:00
}
2016-01-09 02:34:41 +03:00
}
2019-02-06 23:43:38 +03:00
func (r Row) Match(s string) (ok bool) {
if debug.Enabled {
done := debug.Matching("row", s)
defer func() { done(ok) }()
}
2018-02-16 17:36:02 +03:00
if !runes.ExactlyRunesCount(s, r.runes) {
return false
2016-01-09 02:34:41 +03:00
}
2018-02-16 17:36:02 +03:00
return r.matchAll(s)
2016-01-09 02:34:41 +03:00
}
2018-02-16 17:36:02 +03:00
func (r Row) MinLen() int {
return r.runes
2016-01-14 18:29:13 +03:00
}
2018-02-16 17:36:02 +03:00
func (r Row) RunesCount() int {
return r.runes
2016-01-09 02:34:41 +03:00
}
2019-02-06 23:43:38 +03:00
func (r Row) Index(s string) (index int, segments []int) {
if debug.Enabled {
done := debug.Indexing("row", s)
debug.Logf("row: %d vs %d", len(s), r.runes)
defer func() { done(index, segments) }()
}
for j := 0; j <= len(s)-r.runes; { // NOTE: using len() here to avoid counting runes.
2018-02-16 17:36:02 +03:00
i, _ := r.ms[0].Index(s[j:])
if i == -1 {
return -1, nil
2016-01-14 18:29:13 +03:00
}
2018-02-16 17:36:02 +03:00
if r.matchAll(s[i:]) {
return j + i, r.seg
2016-01-09 02:34:41 +03:00
}
2018-02-16 17:36:02 +03:00
_, x := utf8.DecodeRuneInString(s[i:])
j += x
2016-01-09 02:34:41 +03:00
}
return -1, nil
}
2019-02-06 23:43:38 +03:00
func (r Row) Content(cb func(Matcher)) {
for _, m := range r.ms {
cb(m)
}
}
2018-02-16 17:36:02 +03:00
func (r Row) String() string {
2019-02-06 23:43:38 +03:00
return fmt.Sprintf("<row_%d:%s>", r.runes, r.ms)
2018-02-16 17:36:02 +03:00
}
func (r Row) matchAll(s string) bool {
var i int
for _, m := range r.ms {
n := m.RunesCount()
sub := runes.Head(s[i:], n)
if !m.Match(sub) {
return false
}
i += len(sub)
}
return true
2016-01-09 02:34:41 +03:00
}