glob/match/row.go

86 lines
1.2 KiB
Go
Raw Permalink Normal View History

2016-01-09 02:34:41 +03:00
package match
import (
"fmt"
)
type Row struct {
2016-01-14 21:32:02 +03:00
Matchers Matchers
RunesLength int
2016-02-23 14:46:20 +03:00
Segments []int
}
func NewRow(len int, m ...Matcher) Row {
2016-02-23 14:46:20 +03:00
return Row{
Matchers: Matchers(m),
2016-02-23 14:46:20 +03:00
RunesLength: len,
Segments: []int{len},
}
2016-01-09 02:34:41 +03:00
}
2016-01-14 18:29:13 +03:00
func (self Row) matchAll(s string) bool {
2016-01-09 02:34:41 +03:00
var idx int
for _, m := range self.Matchers {
2016-01-20 12:47:43 +03:00
length := m.Len()
var next, i int
for next = range s[idx:] {
i++
if i == length {
break
}
}
if i < length || !m.Match(s[idx:idx+next+1]) {
2016-01-09 02:34:41 +03:00
return false
}
2016-01-20 12:47:43 +03:00
idx += next + 1
2016-01-09 02:34:41 +03:00
}
return true
}
2016-01-20 12:47:43 +03:00
func (self Row) lenOk(s string) bool {
var i int
for _ = range s {
2016-01-20 12:47:43 +03:00
i++
if i >= self.RunesLength {
return true
}
2016-01-09 02:34:41 +03:00
}
2016-01-20 12:47:43 +03:00
return false
}
func (self Row) Match(s string) bool {
return self.lenOk(s) && self.matchAll(s)
2016-01-14 18:29:13 +03:00
}
func (self Row) Len() (l int) {
2016-01-14 21:32:02 +03:00
return self.RunesLength
2016-01-09 02:34:41 +03:00
}
2016-02-05 17:29:41 +03:00
func (self Row) Index(s string) (int, []int) {
2016-01-20 12:47:43 +03:00
if !self.lenOk(s) {
2016-01-14 18:29:13 +03:00
return -1, nil
}
2016-01-09 02:34:41 +03:00
for i := range s {
2016-01-20 12:47:43 +03:00
// this is not strict check but useful
if len(s[i:]) < self.RunesLength {
break
2016-01-14 18:29:13 +03:00
}
2016-01-20 12:47:43 +03:00
if self.matchAll(s[i:]) {
2016-02-23 14:46:20 +03:00
return i, self.Segments
2016-01-09 02:34:41 +03:00
}
}
return -1, nil
}
func (self Row) String() string {
2016-01-14 21:32:02 +03:00
return fmt.Sprintf("<row_%d:[%s]>", self.RunesLength, self.Matchers)
2016-01-09 02:34:41 +03:00
}