1package match
2
3import (
4	"fmt"
5)
6
7type Row struct {
8	Matchers    Matchers
9	RunesLength int
10	Segments    []int
11}
12
13func NewRow(len int, m ...Matcher) Row {
14	return Row{
15		Matchers:    Matchers(m),
16		RunesLength: len,
17		Segments:    []int{len},
18	}
19}
20
21func (self Row) matchAll(s string) bool {
22	var idx int
23	for _, m := range self.Matchers {
24		length := m.Len()
25
26		var next, i int
27		for next = range s[idx:] {
28			i++
29			if i == length {
30				break
31			}
32		}
33
34		if i < length || !m.Match(s[idx:idx+next+1]) {
35			return false
36		}
37
38		idx += next + 1
39	}
40
41	return true
42}
43
44func (self Row) lenOk(s string) bool {
45	var i int
46	for range s {
47		i++
48		if i > self.RunesLength {
49			return false
50		}
51	}
52	return self.RunesLength == i
53}
54
55func (self Row) Match(s string) bool {
56	return self.lenOk(s) && self.matchAll(s)
57}
58
59func (self Row) Len() (l int) {
60	return self.RunesLength
61}
62
63func (self Row) Index(s string) (int, []int) {
64	for i := range s {
65		if len(s[i:]) < self.RunesLength {
66			break
67		}
68		if self.matchAll(s[i:]) {
69			return i, self.Segments
70		}
71	}
72	return -1, nil
73}
74
75func (self Row) String() string {
76	return fmt.Sprintf("<row_%d:[%s]>", self.RunesLength, self.Matchers)
77}
78