github.com/yaling888/clash@v1.53.0/component/geodata/router/condition.go (about)

     1  package router
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/yaling888/clash/component/geodata/strmatcher"
     8  )
     9  
    10  var matcherTypeMap = map[Domain_Type]strmatcher.Type{
    11  	Domain_Plain:  strmatcher.Substr,
    12  	Domain_Regex:  strmatcher.Regex,
    13  	Domain_Domain: strmatcher.Domain,
    14  	Domain_Full:   strmatcher.Full,
    15  }
    16  
    17  func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
    18  	matcherType, f := matcherTypeMap[domain.Type]
    19  	if !f {
    20  		return nil, fmt.Errorf("unsupported domain type %v", domain.Type)
    21  	}
    22  
    23  	matcher, err := matcherType.New(domain.Value)
    24  	if err != nil {
    25  		return nil, fmt.Errorf("failed to create domain matcher, base error: %w", err)
    26  	}
    27  
    28  	return matcher, nil
    29  }
    30  
    31  type DomainMatcher struct {
    32  	matchers strmatcher.IndexMatcher
    33  	not      bool
    34  }
    35  
    36  func NewMphMatcherGroup(domains []*Domain, not bool) (*DomainMatcher, error) {
    37  	g := strmatcher.NewMphMatcherGroup()
    38  	for _, d := range domains {
    39  		matcherType, f := matcherTypeMap[d.Type]
    40  		if !f {
    41  			return nil, fmt.Errorf("unsupported domain type %v", d.Type)
    42  		}
    43  		_, err := g.AddPattern(d.Value, matcherType)
    44  		if err != nil {
    45  			return nil, err
    46  		}
    47  	}
    48  	g.Build()
    49  	return &DomainMatcher{
    50  		matchers: g,
    51  		not:      not,
    52  	}, nil
    53  }
    54  
    55  // NewDomainMatcher new domain matcher.
    56  func NewDomainMatcher(domains []*Domain, not bool) (*DomainMatcher, error) {
    57  	g := new(strmatcher.MatcherGroup)
    58  	for _, d := range domains {
    59  		m, err := domainToMatcher(d)
    60  		if err != nil {
    61  			return nil, err
    62  		}
    63  		g.Add(m)
    64  	}
    65  
    66  	return &DomainMatcher{
    67  		matchers: g,
    68  		not:      not,
    69  	}, nil
    70  }
    71  
    72  func (m *DomainMatcher) ApplyDomain(domain string) bool {
    73  	if m.not {
    74  		return len(m.matchers.Match(strings.ToLower(domain))) == 0
    75  	}
    76  	return len(m.matchers.Match(strings.ToLower(domain))) > 0
    77  }