github.com/mithrandie/csvq@v1.18.1/lib/syntax/store.go (about)

     1  package syntax
     2  
     3  import (
     4  	"strings"
     5  )
     6  
     7  type Store struct {
     8  	Syntax Syntax
     9  }
    10  
    11  func NewStore() *Store {
    12  	return &Store{
    13  		Syntax: CsvqSyntax,
    14  	}
    15  }
    16  
    17  func (s Store) Search(keys []string) []Expression {
    18  	exprs := s.searchSyntax(keys, s.Syntax)
    19  	list := make([]string, 0, len(exprs))
    20  	for _, e := range exprs {
    21  		list = append(list, e.Label)
    22  	}
    23  	return exprs
    24  }
    25  
    26  func (s Store) searchSyntax(keys []string, syntax Syntax) []Expression {
    27  	if len(keys) < 1 {
    28  		return syntax
    29  	}
    30  
    31  	list := make([]Expression, 0, len(syntax))
    32  	for _, exp := range syntax {
    33  		if e := s.search(keys, exp); 0 < len(e.Grammar) || 0 < len(e.Description.Template) {
    34  			list = append(list, e)
    35  		} else if 0 < len(exp.Children) {
    36  			if c := s.searchSyntax(keys, exp.Children); c != nil {
    37  				list = append(list, c...)
    38  			}
    39  		}
    40  	}
    41  
    42  	return list
    43  }
    44  
    45  func (s Store) search(keys []string, exp Expression) Expression {
    46  	if strings.EqualFold(strings.Join(keys, " "), exp.Label) || s.contains(keys, exp.Label, "") {
    47  		return exp
    48  	}
    49  
    50  	defs := make([]Definition, 0, len(exp.Grammar))
    51  	for _, g := range exp.Grammar {
    52  		if s.contains(keys, exp.Label, g.Name.String()) {
    53  			defs = append(defs, g)
    54  		}
    55  	}
    56  
    57  	if len(defs) < 1 {
    58  		exp.Description.Template = ""
    59  	}
    60  
    61  	exp.Grammar = defs
    62  	return exp
    63  }
    64  
    65  func (s Store) contains(keys []string, content string, name string) bool {
    66  	content = strings.ToUpper(content)
    67  	name = strings.ToUpper(name)
    68  	for _, key := range keys {
    69  		if !strings.Contains(content, strings.ToUpper(key)) && !strings.Contains(name, strings.ToUpper(key)) {
    70  			return false
    71  		}
    72  	}
    73  	return true
    74  }