Browse Source

Make ParsePattern public

The goal here is to make it easy for people to write thin wrappers
around the built-in Patterns.
Carl Jackson 11 years ago
parent
commit
83e1241fde
3 changed files with 40 additions and 25 deletions
  1. +4
    -20
      web/mux.go
  2. +35
    -4
      web/pattern.go
  3. +1
    -1
      web/router.go

+ 4
- 20
web/mux.go View File

@ -28,27 +28,11 @@ A middleware (the untyped parameter in Use() and Insert()) must be one of the
following types: following types:
- func(http.Handler) http.Handler - func(http.Handler) http.Handler
- func(c *web.C, http.Handler) http.Handler - func(c *web.C, http.Handler) http.Handler
All of the route-adding functions on Mux take two untyped parameters: pattern All of the route-adding functions on Mux take two untyped parameters: pattern
and handler. Pattern must be one of the following types:
- string. It will be interpreted as a Sinatra-like pattern. In
particular, the following syntax is recognized:
- a path segment starting with with a colon will match any
string placed at that position. e.g., "/:name" will match
"/carl", binding "name" to "carl".
- a pattern ending with "/*" will match any route with that
prefix. For instance, the pattern "/u/:name/*" will match
"/u/carl/" and "/u/carl/projects/123", but not "/u/carl"
(because there is no trailing slash). In addition to any names
bound in the pattern, the special name "*" is bound to the
unmatched tail of the match, but including the leading "/". So
for the two matching examples above, "*" would be bound to "/"
and "/projects/123" respectively.
- regexp.Regexp. The library assumes that it is a Perl-style regexp that
is anchored on the left (i.e., the beginning of the string). If your
regexp is not anchored on the left, a hopefully-identical
left-anchored regexp will be created and used instead.
- web.Pattern
Handler must be one of the following types:
and handler. Pattern will be passed to ParsePattern, which takes a web.Pattern,
a string, or a regular expression (more information can be found in the
ParsePattern documentation). Handler must be one of the following types:
- http.Handler - http.Handler
- web.Handler - web.Handler
- func(w http.ResponseWriter, r *http.Request) - func(w http.ResponseWriter, r *http.Request)


+ 35
- 4
web/pattern.go View File

@ -31,8 +31,39 @@ type Pattern interface {
Run(r *http.Request, c *C) Run(r *http.Request, c *C)
} }
func parsePattern(p interface{}) Pattern {
switch v := p.(type) {
/*
ParsePattern is used internally by Goji to parse route patterns. It is exposed
publicly to make it easier to write thin wrappers around the built-in Pattern
implementations.
Although its parameter has type interface{}, ParsePattern only accepts arguments
of three types:
- web.Pattern, which is passed through
- string, which is interpreted as a Sinatra-like URL pattern. In
particular, the following syntax is recognized:
- a path segment starting with with a colon will match any
string placed at that position. e.g., "/:name" will match
"/carl", binding "name" to "carl".
- a pattern ending with "/*" will match any route with that
prefix. For instance, the pattern "/u/:name/*" will match
"/u/carl/" and "/u/carl/projects/123", but not "/u/carl"
(because there is no trailing slash). In addition to any names
bound in the pattern, the special key "*" is bound to the
unmatched tail of the match, but including the leading "/". So
for the two matching examples above, "*" would be bound to "/"
and "/projects/123" respectively.
- regexp.Regexp, which is assumed to be a Perl-style regular expression
that is anchored on the left (i.e., the beginning of the string). If
your regular expression is not anchored on the left, a
hopefully-identical left-anchored regular expression will be created
and used instead.
ParsePattern fatally exits (using log.Fatalf) if it is passed a value of an
unexpected type. It is the caller's responsibility to ensure that ParsePattern
is called in a type-safe manner.
*/
func ParsePattern(raw interface{}) Pattern {
switch v := raw.(type) {
case Pattern: case Pattern:
return v return v
case *regexp.Regexp: case *regexp.Regexp:
@ -40,8 +71,8 @@ func parsePattern(p interface{}) Pattern {
case string: case string:
return parseStringPattern(v) return parseStringPattern(v)
default: default:
log.Fatalf("Unknown pattern type %v. Expected a web.Pattern, "+
"regexp.Regexp, or a string.", p)
log.Fatalf("Unknown pattern type %T. Expected a web.Pattern, "+
"regexp.Regexp, or a string.", v)
} }
panic("log.Fatalf does not return") panic("log.Fatalf does not return")
} }

+ 1
- 1
web/router.go View File

@ -141,7 +141,7 @@ func (rt *router) route(c *C, w http.ResponseWriter, r *http.Request) {
} }
func (rt *router) handleUntyped(p interface{}, m method, h interface{}) { func (rt *router) handleUntyped(p interface{}, m method, h interface{}) {
rt.handle(parsePattern(p), m, parseHandler(h))
rt.handle(ParsePattern(p), m, parseHandler(h))
} }
func (rt *router) handle(p Pattern, m method, h Handler) { func (rt *router) handle(p Pattern, m method, h Handler) {


Loading…
Cancel
Save