diff --git a/web/mux.go b/web/mux.go index 0004bae..3908de5 100644 --- a/web/mux.go +++ b/web/mux.go @@ -28,27 +28,11 @@ A middleware (the untyped parameter in Use() and Insert()) must be one of the following types: - func(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 -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 - web.Handler - func(w http.ResponseWriter, r *http.Request) diff --git a/web/pattern.go b/web/pattern.go index 0d27c51..99ca59e 100644 --- a/web/pattern.go +++ b/web/pattern.go @@ -31,8 +31,39 @@ type Pattern interface { 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: return v case *regexp.Regexp: @@ -40,8 +71,8 @@ func parsePattern(p interface{}) Pattern { case string: return parseStringPattern(v) 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") } diff --git a/web/router.go b/web/router.go index d4b88d5..277f524 100644 --- a/web/router.go +++ b/web/router.go @@ -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{}) { - rt.handle(parsePattern(p), m, parseHandler(h)) + rt.handle(ParsePattern(p), m, parseHandler(h)) } func (rt *router) handle(p Pattern, m method, h Handler) {