-
Notifications
You must be signed in to change notification settings - Fork 0
/
options.go
81 lines (69 loc) · 2.62 KB
/
options.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
package urit
import (
"regexp"
"strings"
)
// FixedMatchOption is the option interface for checking if a fixed path part matches the template
//
// An example is provided by the CaseInsensitiveFixed - which allows fixed path parts to be matched
// regardless of case
type FixedMatchOption interface {
Match(value string, expected string, pathPos int, vars PathVars) bool
}
// VarMatchOption is the option interface for checking if a variable part matches the template
//
// It can also be used to adjust the path variable found
type VarMatchOption interface {
Applicable(value string, position int, name string, rx *regexp.Regexp, rxs string, pathPos int, vars PathVars) bool
Match(value string, position int, name string, rx *regexp.Regexp, rxs string, pathPos int, vars PathVars) (string, bool)
}
var (
_CaseInsensitiveFixed = &caseInsensitiveFixed{}
_PathRegexCheck = &pathRegexChecker{}
)
var (
CaseInsensitiveFixed = _CaseInsensitiveFixed // is a FixedMatchOption that can be used with templates to allow case-insensitive fixed path parts
PathRegexCheck = _PathRegexCheck // is a VarMatchOption that can be used with Template.PathFrom or Template.RequestFrom to check that vars passed in match regexes for the path part
)
type fixedMatchOptions []FixedMatchOption
type varMatchOptions []VarMatchOption
func (opts fixedMatchOptions) check(value string, expected string, pathPos int, vars PathVars) bool {
ok := false
for _, o := range opts {
ok = o.Match(value, expected, pathPos, vars)
if ok {
break
}
}
return ok
}
func (opts varMatchOptions) check(value string, position int, name string, rx *regexp.Regexp, rxs string, pathPos int, vars PathVars) (string, bool, bool) {
ok := false
result := value
checked := 0
for _, o := range opts {
if o.Applicable(value, position, name, rx, rxs, pathPos, vars) {
checked++
if s, oko := o.Match(value, position, name, rx, rxs, pathPos, vars); oko {
result = s
ok = oko
break
}
}
}
return result, ok, checked > 0
}
type caseInsensitiveFixed struct{}
func (o *caseInsensitiveFixed) Match(value string, expected string, pathPos int, vars PathVars) bool {
return value == expected || strings.EqualFold(value, expected)
}
type pathRegexChecker struct{}
func (o *pathRegexChecker) Applicable(value string, position int, name string, rx *regexp.Regexp, rxs string, pathPos int, vars PathVars) bool {
return rx != nil
}
func (o *pathRegexChecker) Match(value string, position int, name string, rx *regexp.Regexp, rxs string, pathPos int, vars PathVars) (string, bool) {
if rx != nil && !rx.MatchString(value) {
return value, false
}
return value, true
}