-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.go
98 lines (86 loc) · 1.65 KB
/
filter.go
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
package main
import (
"reflect"
"regexp"
)
type Filterable interface {
Match(pattern *regexp.Regexp) bool
}
type FilterableChannel chan Filterable
func StrMatch(s string, re *regexp.Regexp) bool {
return nil != re.FindStringIndex(s)
}
func patternFilter(in chan Filterable, pattern string, include bool) (out FilterableChannel) {
out = make(chan Filterable)
re, err := regexp.Compile(pattern)
if err != nil {
panic(err)
}
go func() {
for l := range in {
if l.Match(re) {
if include {
out <- l
}
} else {
if !include {
out <- l
}
}
}
close(out)
}()
return
}
func (in FilterableChannel) applyIncludeFilter(patterns []string) (out FilterableChannel) {
out = in
for _, p := range patterns {
if p != "" {
out = patternFilter(out, p, true)
}
}
return
}
func (in FilterableChannel) applyExcludeFilter(patterns []string) (out FilterableChannel) {
out = in
for _, p := range patterns {
if p != "" {
out = patternFilter(out, p, false)
}
}
return
}
func WrapFilterableChannel(ch interface{}) FilterableChannel {
t := reflect.TypeOf(ch)
if t.Kind() != reflect.Chan {
panic("ch must be channel")
}
ret := make(FilterableChannel)
go func() {
v := reflect.ValueOf(ch)
for {
x, ok := v.Recv()
if !ok {
close(ret)
return
}
if t, ok := x.Interface().(Filterable); ok {
ret <- t
}
}
}()
return ret
}
func (in FilterableChannel) UnwrapFilterableChannel(out interface{}) {
t := reflect.TypeOf(out)
if t.Kind() != reflect.Chan {
panic("out must be channel")
}
go func() {
v := reflect.ValueOf(out)
for x := range in {
v.Send(reflect.ValueOf(x))
}
v.Close()
}()
}