-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathline.go
More file actions
124 lines (111 loc) · 2.68 KB
/
line.go
File metadata and controls
124 lines (111 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package table
import (
"regexp"
"strings"
)
// FieldMatcher is a function type which is consumed by different table Cell finder functions.
type FieldMatcher func([]string) (string, bool)
// LineContaining returns a predicate checking whether a line contains specified tokens
func LineContaining(ss ...string) func(string) bool {
return func(line string) bool {
for _, s := range ss {
if !strings.Contains(line, s) {
return false
}
}
return true
}
}
// LineContainingSlices is the slice version of line containing
func LineContainingSlices(ls ...[]string) func(string) bool {
m := map[string]bool{}
for _, l := range ls {
for _, s := range l {
m[s] = true
}
}
return LineContaining(strBoolMapKeys(m)...)
}
// strBoolMapKeys returns a list of keys from a map[string]bool
func strBoolMapKeys(m map[string]bool) []string {
keys := make([]string, len(m))
i := 0
for s := range m {
keys[i] = s
i++
}
return keys
}
// LineContainingAny behaves like line containing but any given slice is enough
func LineContainingAny(ls ...[]string) func(string) bool {
predicates := make([]func(string) bool, len(ls))
for i, ss := range ls {
predicates[i] = LineContaining(ss...)
}
return func(line string) bool {
for _, predicate := range predicates {
if predicate(line) {
return true
}
}
return false
}
}
// AllAreMatched accepts lines until all predicates are matched
func AllAreMatched(pp ...func(string) bool) func(string) bool {
index := 0
return func(line string) bool {
if index >= len(pp) {
return true
}
if pp[index](line) {
index++
}
return index >= len(pp)
}
}
// AnyMatched accepts line any one of predicates is satisfied
func AnyMatched(pp ...func(string) bool) func(string) bool {
return func(line string) bool {
if len(pp) == 0 {
return true
}
for _, p := range pp {
if p(line) {
return true
}
}
return false
}
}
// NonEmptyLine checks whether line is not empty
func NonEmptyLine() func(string) bool {
return func(s string) bool {
return !isWhiteSpace(s)
}
}
// EmptyLine matches empty line
func EmptyLine() func(string) bool {
return func(s string) bool {
return isWhiteSpace(s)
}
}
// LineFieldMatcher provides matchers for whole line or specific cell content
type LineFieldMatcher struct {
Re *regexp.Regexp
Sep string
}
// Find returns a matching cell in a given line.
func (fm LineFieldMatcher) Find(line []string) (string, bool) {
for _, s := range line {
if fm.Re.MatchString(s) {
return s, true
}
}
return "", false
}
// FindLine returns a matching line.
func (fm LineFieldMatcher) FindLine(fields []string) (string, bool) {
line := strings.Join(fields, fm.Sep)
return line, fm.Re.MatchString(line)
}