package router import ( "fmt" "strings" "github.com/Dreamacro/clash/component/geodata/strmatcher" ) var matcherTypeMap = map[Domain_Type]strmatcher.Type{ Domain_Plain: strmatcher.Substr, Domain_Regex: strmatcher.Regex, Domain_Domain: strmatcher.Domain, Domain_Full: strmatcher.Full, } func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) { matcherType, f := matcherTypeMap[domain.Type] if !f { return nil, fmt.Errorf("unsupported domain type %v", domain.Type) } matcher, err := matcherType.New(domain.Value) if err != nil { return nil, fmt.Errorf("failed to create domain matcher, base error: %s", err.Error()) } return matcher, nil } type DomainMatcher struct { matchers strmatcher.IndexMatcher } func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) { g := strmatcher.NewMphMatcherGroup() for _, d := range domains { matcherType, f := matcherTypeMap[d.Type] if !f { return nil, fmt.Errorf("unsupported domain type %v", d.Type) } _, err := g.AddPattern(d.Value, matcherType) if err != nil { return nil, err } } g.Build() return &DomainMatcher{ matchers: g, }, nil } // NewDomainMatcher new domain matcher. func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) { g := new(strmatcher.MatcherGroup) for _, d := range domains { m, err := domainToMatcher(d) if err != nil { return nil, err } g.Add(m) } return &DomainMatcher{ matchers: g, }, nil } func (m *DomainMatcher) ApplyDomain(domain string) bool { return len(m.matchers.Match(strings.ToLower(domain))) > 0 }