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
|
// SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net>
// SPDX-License-Identifier: Apache-2.0
package pathrouter
import (
. "go.xyrillian.de/gg/option"
)
// Here is a [Matcher] that matches effectively empty subpaths, that is:
// subpaths that are either empty or only contain a heretofore unmatched trailing slash.
// It can be used to opt-in to allowing trailing slashes at the ends of URL paths:
//
// // only matches "/foo/bar"
// pr.Element("foo", pr.Element("bar", pr.Handlers(...))
//
// // also matches "/foo/bar/"
// pr.Element("foo", pr.Element("bar", pr.Here(pr.Handlers(...)))
//
// The next matcher must match only the empty path, so currently only [Handlers] is allowed.
//
// Here is provided as a useful shorthand, but could be implemented using the other matchers like so:
//
// // this...
// m := pr.Here(pr.Handlers(byMethod))
//
// // ...is equivalent to this
// h := pr.Handlers(byMethod)
// m := pr.Choice(h, pr.Element("/", h))
//
// The name "Here" makes sense when Here() appears as one of several options within Choice(),
// where the other options would match subpaths, while Here() matches, well, "here".
// The example in the package docstring illustrates this.
func Here(matcher Matcher) Matcher {
return here(matcher.downcast())
}
func here(matcher realMatcher) Matcher {
if matcher.minLength != 0 || matcher.maxLength != Some(0) {
panic("matcher within Here() must be Handlers()")
}
return realMatcher{
minLength: 0,
maxLength: Some(1),
accept: func(path []string, vars map[string]string) HandlerFunc {
if len(path) == 0 || (len(path) == 1 && path[0] == "") {
return matcher.accept(nil, vars)
}
return nil
},
}
}
|