2016-01-08 20:14:31 +03:00
|
|
|
package match
|
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
)
|
2016-01-08 20:14:31 +03:00
|
|
|
|
|
|
|
type AnyOf struct {
|
2018-02-16 17:36:02 +03:00
|
|
|
ms []Matcher
|
|
|
|
min int
|
2016-01-08 20:14:31 +03:00
|
|
|
}
|
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func NewAnyOf(ms ...Matcher) Matcher {
|
|
|
|
a := AnyOf{ms, minLen(ms)}
|
|
|
|
if mis, ok := MatchIndexers(ms); ok {
|
2018-11-24 21:47:12 +03:00
|
|
|
x := IndexedAnyOf{a, mis}
|
|
|
|
if msz, ok := MatchIndexSizers(ms); ok {
|
|
|
|
sz := -1
|
|
|
|
for _, m := range msz {
|
|
|
|
n := m.RunesCount()
|
|
|
|
if sz == -1 {
|
|
|
|
sz = n
|
|
|
|
} else if sz != n {
|
|
|
|
sz = -1
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if sz != -1 {
|
|
|
|
return IndexedSizedAnyOf{x, sz}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return x
|
2018-02-16 17:36:02 +03:00
|
|
|
}
|
|
|
|
return a
|
2016-01-08 20:14:31 +03:00
|
|
|
}
|
|
|
|
|
2018-11-24 21:47:12 +03:00
|
|
|
func MustIndexedAnyOf(ms ...Matcher) MatchIndexer {
|
|
|
|
return NewAnyOf(ms...).(MatchIndexer)
|
|
|
|
}
|
|
|
|
|
|
|
|
func MustIndexedSizedAnyOf(ms ...Matcher) MatchIndexSizer {
|
|
|
|
return NewAnyOf(ms...).(MatchIndexSizer)
|
|
|
|
}
|
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func (a AnyOf) Match(s string) bool {
|
|
|
|
for _, m := range a.ms {
|
2016-01-08 20:14:31 +03:00
|
|
|
if m.Match(s) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func (a AnyOf) MinLen() (n int) {
|
|
|
|
return a.min
|
|
|
|
}
|
2016-02-05 16:57:42 +03:00
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func (a AnyOf) Content() []Matcher {
|
|
|
|
return a.ms
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a AnyOf) String() string {
|
|
|
|
return fmt.Sprintf("<any_of:[%s]>", Matchers(a.ms))
|
|
|
|
}
|
|
|
|
|
|
|
|
type IndexedAnyOf struct {
|
|
|
|
AnyOf
|
|
|
|
ms []MatchIndexer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a IndexedAnyOf) Index(s string) (int, []int) {
|
|
|
|
index := -1
|
2016-02-23 00:26:06 +03:00
|
|
|
segments := acquireSegments(len(s))
|
2018-02-16 17:36:02 +03:00
|
|
|
for _, m := range a.ms {
|
|
|
|
i, seg := m.Index(s)
|
|
|
|
if i == -1 {
|
2016-01-12 14:06:59 +03:00
|
|
|
continue
|
|
|
|
}
|
2018-02-16 17:36:02 +03:00
|
|
|
if index == -1 || i < index {
|
|
|
|
index = i
|
2016-02-02 22:03:37 +03:00
|
|
|
segments = append(segments[:0], seg...)
|
2016-01-12 14:06:59 +03:00
|
|
|
continue
|
|
|
|
}
|
2018-02-16 17:36:02 +03:00
|
|
|
if i > index {
|
2016-01-12 14:06:59 +03:00
|
|
|
continue
|
|
|
|
}
|
2018-02-16 17:36:02 +03:00
|
|
|
// here i == index
|
2016-02-02 22:03:37 +03:00
|
|
|
segments = appendMerge(segments, seg)
|
2016-01-12 14:06:59 +03:00
|
|
|
}
|
|
|
|
if index == -1 {
|
2016-02-23 00:26:06 +03:00
|
|
|
releaseSegments(segments)
|
2016-01-12 14:06:59 +03:00
|
|
|
return -1, nil
|
|
|
|
}
|
2016-02-02 22:03:37 +03:00
|
|
|
return index, segments
|
2016-01-12 14:06:59 +03:00
|
|
|
}
|
2016-01-11 10:17:19 +03:00
|
|
|
|
2018-02-16 17:36:02 +03:00
|
|
|
func (a IndexedAnyOf) String() string {
|
|
|
|
return fmt.Sprintf("<indexed_any_of:[%s]>", a.ms)
|
2016-01-08 20:14:31 +03:00
|
|
|
}
|
2018-11-24 21:47:12 +03:00
|
|
|
|
|
|
|
type IndexedSizedAnyOf struct {
|
|
|
|
IndexedAnyOf
|
|
|
|
runes int
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a IndexedSizedAnyOf) RunesCount() int {
|
|
|
|
return a.runes
|
|
|
|
}
|