| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 | 
							- package strmatcher
 
- import (
 
- 	"regexp"
 
- )
 
- // Matcher is the interface to determine a string matches a pattern.
 
- type Matcher interface {
 
- 	// Match returns true if the given string matches a predefined pattern.
 
- 	Match(string) bool
 
- }
 
- // Type is the type of the matcher.
 
- type Type byte
 
- const (
 
- 	// Full is the type of matcher that the input string must exactly equal to the pattern.
 
- 	Full Type = iota
 
- 	// Substr is the type of matcher that the input string must contain the pattern as a sub-string.
 
- 	Substr
 
- 	// Domain is the type of matcher that the input string must be a sub-domain or itself of the pattern.
 
- 	Domain
 
- 	// Regex is the type of matcher that the input string must matches the regular-expression pattern.
 
- 	Regex
 
- )
 
- // New creates a new Matcher based on the given pattern.
 
- func (t Type) New(pattern string) (Matcher, error) {
 
- 	switch t {
 
- 	case Full:
 
- 		return fullMatcher(pattern), nil
 
- 	case Substr:
 
- 		return substrMatcher(pattern), nil
 
- 	case Domain:
 
- 		return domainMatcher(pattern), nil
 
- 	case Regex:
 
- 		r, err := regexp.Compile(pattern)
 
- 		if err != nil {
 
- 			return nil, err
 
- 		}
 
- 		return ®exMatcher{
 
- 			pattern: r,
 
- 		}, nil
 
- 	default:
 
- 		panic("Unknown type")
 
- 	}
 
- }
 
- // IndexMatcher is the interface for matching with a group of matchers.
 
- type IndexMatcher interface {
 
- 	// Match returns the the index of a matcher that matches the input. It returns 0 if no such matcher exists.
 
- 	Match(input string) uint32
 
- }
 
- type matcherEntry struct {
 
- 	m  Matcher
 
- 	id uint32
 
- }
 
- // MatcherGroup is an implementation of IndexMatcher.
 
- // Empty initialization works.
 
- type MatcherGroup struct {
 
- 	count         uint32
 
- 	fullMatcher   FullMatcherGroup
 
- 	domainMatcher DomainMatcherGroup
 
- 	otherMatchers []matcherEntry
 
- }
 
- // Add adds a new Matcher into the MatcherGroup, and returns its index. The index will never be 0.
 
- func (g *MatcherGroup) Add(m Matcher) uint32 {
 
- 	g.count++
 
- 	c := g.count
 
- 	switch tm := m.(type) {
 
- 	case fullMatcher:
 
- 		g.fullMatcher.addMatcher(tm, c)
 
- 	case domainMatcher:
 
- 		g.domainMatcher.addMatcher(tm, c)
 
- 	default:
 
- 		g.otherMatchers = append(g.otherMatchers, matcherEntry{
 
- 			m:  m,
 
- 			id: c,
 
- 		})
 
- 	}
 
- 	return c
 
- }
 
- // Match implements IndexMatcher.Match.
 
- func (g *MatcherGroup) Match(pattern string) uint32 {
 
- 	if c := g.fullMatcher.Match(pattern); c > 0 {
 
- 		return c
 
- 	}
 
- 	if c := g.domainMatcher.Match(pattern); c > 0 {
 
- 		return c
 
- 	}
 
- 	for _, e := range g.otherMatchers {
 
- 		if e.m.Match(pattern) {
 
- 			return e.id
 
- 		}
 
- 	}
 
- 	return 0
 
- }
 
- // Size returns the number of matchers in the MatcherGroup.
 
- func (g *MatcherGroup) Size() uint32 {
 
- 	return g.count
 
- }
 
 
  |