strmatcher.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package strmatcher
  2. import "regexp"
  3. type Matcher interface {
  4. Match(string) bool
  5. }
  6. type Type byte
  7. const (
  8. Full Type = iota
  9. Substr
  10. Domain
  11. Regex
  12. )
  13. func (t Type) New(pattern string) (Matcher, error) {
  14. switch t {
  15. case Full:
  16. return fullMatcher(pattern), nil
  17. case Substr:
  18. return substrMatcher(pattern), nil
  19. case Domain:
  20. return domainMatcher(pattern), nil
  21. case Regex:
  22. r, err := regexp.Compile(pattern)
  23. if err != nil {
  24. return nil, err
  25. }
  26. return &regexMatcher{
  27. pattern: r,
  28. }, nil
  29. default:
  30. panic("Unknown type")
  31. }
  32. }
  33. type matcherEntry struct {
  34. m Matcher
  35. id uint32
  36. }
  37. type MatcherGroup struct {
  38. count uint32
  39. fullMatchers map[string]uint32
  40. otherMatchers []matcherEntry
  41. }
  42. func NewMatcherGroup() *MatcherGroup {
  43. return &MatcherGroup{
  44. count: 1,
  45. fullMatchers: make(map[string]uint32),
  46. }
  47. }
  48. func (g *MatcherGroup) Add(m Matcher) uint32 {
  49. c := g.count
  50. g.count++
  51. if fm, ok := m.(fullMatcher); ok {
  52. g.fullMatchers[string(fm)] = c
  53. } else {
  54. g.otherMatchers = append(g.otherMatchers, matcherEntry{
  55. m: m,
  56. id: c,
  57. })
  58. }
  59. return c
  60. }
  61. func (g *MatcherGroup) Match(pattern string) uint32 {
  62. if c, f := g.fullMatchers[pattern]; f {
  63. return c
  64. }
  65. for _, e := range g.otherMatchers {
  66. if e.m.Match(pattern) {
  67. return e.id
  68. }
  69. }
  70. return 0
  71. }
  72. func (g *MatcherGroup) Size() uint32 {
  73. return g.count
  74. }