/
regexp.go
96 lines (70 loc) · 1.81 KB
/
regexp.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
package filter
import (
"context"
"fmt"
"net/url"
"regexp"
"gocloud.dev/blob"
)
func init() {
ctx := context.Background()
err := RegisterFilter(ctx, "regexp", NewRegexpFilter)
if err != nil {
panic(err)
}
}
// type AnyFilter implements the `Filter` interface that determines whether an image should be included in a picturebook using a regular expression.
type RegexpFilter struct {
Filter
mode string
re *regexp.Regexp
}
// NewRegexpFilter returns a new instance of `RegExpFilter` for 'uri' which must be parsable as a valid `net/url` URL instance.
// That URI must contain a host value of either 'include' or 'exclude' and query parameter 'pattern' containing a valid regular
// expression used to test file paths for inclusion in a picturebook.
func NewRegexpFilter(ctx context.Context, uri string) (Filter, error) {
u, err := url.Parse(uri)
if err != nil {
return nil, fmt.Errorf("Failed to parse URL, %w", err)
}
var mode string
switch u.Host {
case "include":
mode = "include"
case "exclude":
mode = "exclude"
default:
return nil, fmt.Errorf("Invalid mode '%s'", u.Host)
}
q := u.Query()
pat := q.Get("pattern")
if pat == "" {
return nil, fmt.Errorf("Missing ?pattern= parameter")
}
re, err := regexp.Compile(pat)
if err != nil {
return nil, fmt.Errorf("Failed to compile pattern, %w", err)
}
f := &RegexpFilter{
mode: mode,
re: re,
}
return f, nil
}
// Continues returns a boolean value signaling whether or not 'path' should be included in a picturebook.
func (f *RegexpFilter) Continue(ctx context.Context, bucket *blob.Bucket, path string) (bool, error) {
match := f.re.MatchString(path)
switch f.mode {
case "include":
if !match {
return false, nil
}
case "exclude":
if match {
return false, nil
}
default:
// pass
}
return true, nil
}