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 }