2016-01-09 02:34:41 +03:00
|
|
|
package match
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2022-06-15 11:05:05 +03:00
|
|
|
"unicode/utf8"
|
2016-01-09 02:34:41 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2016-02-24 12:36:15 +03:00
|
|
|
func NewRow(len int, m ...Matcher) Row {
|
2016-02-23 14:46:20 +03:00
|
|
|
return Row{
|
2016-02-24 12:36:15 +03:00
|
|
|
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()
|
|
|
|
|
2022-06-15 11:05:05 +03:00
|
|
|
var runeCount, byteIdx int
|
|
|
|
var r rune
|
|
|
|
for _, r = range s[idx:] {
|
|
|
|
runeCount++
|
|
|
|
byteIdx += utf8.RuneLen(r)
|
|
|
|
if runeCount == length {
|
2016-01-20 12:47:43 +03:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-15 11:05:05 +03:00
|
|
|
if runeCount < length || !m.Match(s[idx:idx+byteIdx]) {
|
2016-01-09 02:34:41 +03:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-06-15 11:05:05 +03:00
|
|
|
idx += byteIdx
|
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
|
2016-08-15 07:02:39 +03:00
|
|
|
for range s {
|
2016-01-20 12:47:43 +03:00
|
|
|
i++
|
2016-10-23 00:02:45 +03:00
|
|
|
if i > self.RunesLength {
|
|
|
|
return false
|
2016-01-20 12:47:43 +03:00
|
|
|
}
|
2016-01-09 02:34:41 +03:00
|
|
|
}
|
2016-10-23 00:02:45 +03:00
|
|
|
return self.RunesLength == i
|
2016-01-20 12:47:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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-09 02:34:41 +03:00
|
|
|
for i := range s {
|
2016-01-20 12:47:43 +03:00
|
|
|
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
|
|
|
}
|