github.com/go-enry/go-enry@v1.7.3/data/rule/rule.go (about)

     1  // Package rule contains rule-based heuristic implementations.
     2  // It is used in the generated code in content.go for disambiguation of languages
     3  // with colliding extensions, based on regexps from Linguist data.
     4  package rule
     5  
     6  // Heuristic consist of (a number of) rules where each, if matches,
     7  // identifes content as belonging to a programming language(s).
     8  type Heuristic interface {
     9  	Matcher
    10  	Languages() []string
    11  }
    12  
    13  // Matcher checks if the data matches (number of) pattern.
    14  // Every heuristic rule below implements this interface.
    15  // A regexp.Regexp satisfies this interface and can be used instead.
    16  type Matcher interface {
    17  	Match(data []byte) bool
    18  }
    19  
    20  // languages struct incapsulate data common to every Matcher: all languages
    21  // that it identifies.
    22  type languages struct {
    23  	langs []string
    24  }
    25  
    26  // Languages returns all languages, identified by this Matcher.
    27  func (l languages) Languages() []string {
    28  	return l.langs
    29  }
    30  
    31  // MatchingLanguages is a helper to create new languages.
    32  func MatchingLanguages(langs ...string) languages {
    33  	return languages{langs}
    34  }
    35  
    36  // Implements a Heuristic.
    37  type or struct {
    38  	languages
    39  	pattern Matcher
    40  }
    41  
    42  // Or rule matches, if a single matching pattern exists.
    43  // It recives only one pattern as it relies on compile-time optimization that
    44  // represtes union with | inside a single regexp.
    45  func Or(l languages, r Matcher) Heuristic {
    46  	return or{l, r}
    47  }
    48  
    49  // Match implements rule.Matcher.
    50  func (r or) Match(data []byte) bool {
    51  	return r.pattern.Match(data)
    52  }
    53  
    54  // Implements a Heuristic.
    55  type and struct {
    56  	languages
    57  	patterns []Matcher
    58  }
    59  
    60  // And rule matches, if each of the patterns does match.
    61  func And(l languages, m ...Matcher) Heuristic {
    62  	return and{l, m}
    63  }
    64  
    65  // Match implements data.Matcher.
    66  func (r and) Match(data []byte) bool {
    67  	for _, p := range r.patterns {
    68  		if !p.Match(data) {
    69  			return false
    70  		}
    71  	}
    72  	return true
    73  }
    74  
    75  // Implements a Heuristic.
    76  type not struct {
    77  	languages
    78  	Patterns []Matcher
    79  }
    80  
    81  // Not rule matches if none of the patterns match.
    82  func Not(l languages, r ...Matcher) Heuristic {
    83  	return not{l, r}
    84  }
    85  
    86  // Match implements data.Matcher.
    87  func (r not) Match(data []byte) bool {
    88  	for _, p := range r.Patterns {
    89  		if p.Match(data) {
    90  			return false
    91  		}
    92  	}
    93  	return true
    94  }
    95  
    96  // Implements a Heuristic.
    97  type always struct {
    98  	languages
    99  }
   100  
   101  // Always rule always matches. Often is used as a default fallback.
   102  func Always(l languages) Heuristic {
   103  	return always{l}
   104  }
   105  
   106  // Match implements Matcher.
   107  func (r always) Match(data []byte) bool {
   108  	return true
   109  }