2016-01-09 02:34:41 +03:00
|
|
|
package match
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2018-02-16 17:36:02 +03:00
|
|
|
"unicode/utf8"
|
|
|
|
|
|
|
|
"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
|
|
|
}
|
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func (r Row) Match(s string) bool {
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func (r Row) Index(s string) (int, []int) {
|
|
|
|
for j := 0; j < len(s)-r.runes; {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func (r Row) String() string {
|
|
|
|
return fmt.Sprintf("<row_%d:[%s]>", r.runes, r.ms)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|