/
parse.go
89 lines (81 loc) · 2.05 KB
/
parse.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
package filter
import (
"errors"
"strconv"
"strings"
log "github.com/Sirupsen/logrus"
"golang.org/x/net/context"
)
var (
ErrFilterNotFound = errors.New("filter not found")
ErrBadFilterParameter = errors.New("bad filter parameter")
ErrMissingFilterParameter = errors.New("missing filter parameter")
)
type FilterBuilder func(parts []string) (Filter, int, error)
func Parse(ctx context.Context, m map[string]FilterBuilder, str string) (Chain, error) {
// predefined filter
c := predefined(str)
if c != nil {
return c, nil
}
// parse filter
c = Chain{}
parts := strings.Split(str, ",")
for {
fn, found := m[parts[0]]
if !found {
return nil, ErrFilterNotFound
}
f, adv, err := fn(parts)
if err != nil {
return nil, err
}
c = append(c, f)
if len(parts) <= adv {
break
}
parts = parts[adv:]
}
return c, nil
}
func ParseRect(str string) (int, int, int, int, error) {
parts := strings.Split(str, "-")
if len(parts) != 2 {
log.Warnf("Unable to parse rectangle %s", str)
return 0, 0, 0, 0, ErrBadFilterParameter
}
x, y, err := ParseDimensions(parts[0])
if err != nil {
return 0, 0, 0, 0, ErrBadFilterParameter
}
w, h, err := ParseDimensions(parts[1])
if err != nil {
return 0, 0, 0, 0, ErrBadFilterParameter
}
return x, y, w, h, nil
}
func ParseDimensions(str string) (int, int, error) {
parts := strings.Split(str, "x")
if len(parts) != 2 {
log.Warnf("Unable to parse dimensions %s", str)
return 0, 0, ErrBadFilterParameter
}
x, err := strconv.ParseInt(parts[0], 10, 32)
if err != nil || x < 0 {
log.Warnf("Unable to parse dimensions %s (not a positive integer)", str)
return 0, 0, ErrBadFilterParameter
}
y, err := strconv.ParseInt(parts[1], 10, 32)
if err != nil || y < 0 {
log.Warnf("Unable to parse dimensions %s (not a positive integer)", str)
return 0, 0, ErrBadFilterParameter
}
return int(x), int(y), nil
}
func ParseModifier(str string, allowed string) (byte, string) {
mod := str[len(str)-1]
if strings.ContainsRune(allowed, rune(mod)) {
return mod, str[:len(str)-1]
}
return 0, str
}