about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranck Cuny <franck@lumberjaph.net>2013-04-22 20:30:25 -0700
committerFranck Cuny <franck@lumberjaph.net>2013-04-22 20:30:41 -0700
commit0ad196a0130164e6a18da7ee20156de0d508f8a3 (patch)
tree61503d325caba2ee6091625f89fe977015a95ffa
parentIn each route, keep a map of HTTP methods available. (diff)
downloadpath-router-0ad196a0130164e6a18da7ee20156de0d508f8a3.tar.gz
Change the interface to create routes.
Previously, to create a route, a user would call the AddRoute function,
and pass three arguments (the path, the HTTP method and the function).

This interface is way too limited if we need/want to expand what a route
is in the future.

Instead, we keep calling the AddRoute function to create a route, but
this time the user pass a Route structure.  The AddRoute will then
apply a few transformations and connect the route to the router.
-rw-r--r--dispatcher.go27
-rw-r--r--mooh.go1
-rw-r--r--request_test.go3
-rw-r--r--route.go63
-rw-r--r--router_test.go22
5 files changed, 52 insertions, 64 deletions
diff --git a/dispatcher.go b/dispatcher.go
index 3b98b5f..7e17e54 100644
--- a/dispatcher.go
+++ b/dispatcher.go
@@ -8,7 +8,7 @@ import (
 )
 
 type Dispatcher struct {
-	Routes      []Route
+	Routes      []*Route
 	RouteAccess map[string]*Route
 }
 
@@ -18,26 +18,26 @@ func BuildDispatcher() Dispatcher {
 	return router
 }
 
-func (self *Dispatcher) GetRoute(path string) *Route {
-	r := self.RouteAccess[path]
+func (self *Dispatcher) GetRoute(route *Route) *Route {
+	// r := self.RouteAccess[route.Path]
 
-	if r != nil {
-		return r
-	}
+	// if r != nil {
+	// 	return r
+	// }
 
 	return nil
 }
 
-func (self *Dispatcher) AddRoute(path string, method string, code func(*Request) (Response, error)) {
-	r := self.GetRoute(path)
+func (self *Dispatcher) AddRoute(route *Route) {
+	r := self.GetRoute(route)
 
 	if r == nil {
-		route := MakeRoute(path, method, code)
+		route.init()
 		self.Routes = append(self.Routes, route)
-		self.RouteAccess[path] = &route
+	// 	self.RouteAccess[route.Path] = route
 	} else {
-		r.Executors[method] = code
-		r.Methods[method] = true
+	// 	// r.Executors[method] = code
+	// 	// r.Methods[method] = true
 	}
 }
 
@@ -62,7 +62,6 @@ func (self *Dispatcher) Match(request *http.Request) (*Match, error) {
 	} else {
 		return self.disambiguateMatches(request.URL.Path, matches)
 	}
-	return nil, nil
 }
 
 func (self *Dispatcher) disambiguateMatches(path string, matches []*Match) (*Match, error) {
@@ -70,7 +69,7 @@ func (self *Dispatcher) disambiguateMatches(path string, matches []*Match) (*Mat
 	found := []*Match{}
 
 	for _, m := range matches {
-		req := m.Route.RequiredNamedComponents
+		req := m.Route.requiredNamedComponents
 		vars := len(req)
 		if min == -1 || vars < min {
 			found = append(found, m)
diff --git a/mooh.go b/mooh.go
index a8858a6..2bcca75 100644
--- a/mooh.go
+++ b/mooh.go
@@ -10,6 +10,7 @@ func (self *Dispatcher) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
 	match, err := self.Match(req)
 
 	if err != nil {
+		fmt.Println(err)
 		fmt.Printf("oups")
 		return
 	}
diff --git a/request_test.go b/request_test.go
index e622b7e..5eb58a0 100644
--- a/request_test.go
+++ b/request_test.go
@@ -13,12 +13,13 @@ func testRequestRoute(req *Request) (Response, error) {
 
 func buildDispatcher() Dispatcher {
 	router := BuildDispatcher()
-	router.AddRoute("/foo/:bar", "GET", testRequestRoute)
+	router.AddRoute(&Route{Method: "GET", Path: "/foo/:bar", Code: testRequestRoute})
 	return router
 }
 
 func TestBasicRequest(t *testing.T) {
 	router := buildDispatcher()
+	t.Log(router.Routes[0].components)
 	r := &http.Request{Method: "GET", URL: &url.URL{Path: "/foo/bar"}}
 	m, _ := router.Match(r)
 	request := NewRequest(r, m)
diff --git a/route.go b/route.go
index 9fc86ee..b724a04 100644
--- a/route.go
+++ b/route.go
@@ -9,14 +9,14 @@ type fn func(*Request) (Response, error)
 type fns map[string]fn
 
 type Route struct {
+	Method                  string
 	Path                    string
-	Executors               fns
-	Components              []string
-	RequiredNamedComponents map[string]bool
-	OptionalNamedComponents map[string]bool
-	Length                  int
-	LengthWithoutOptional   int
-	Methods                 map[string]bool
+	Code                    fn
+	components              []string
+	requiredNamedComponents map[string]bool
+	optionalNamedComponents map[string]bool
+	length                  int
+	lengthWithoutOptional   int
 }
 
 type Match struct {
@@ -38,17 +38,17 @@ func (self *Route) convertComponentName(name string) string {
 
 func (self *Route) Match(method string, components []string) *Match {
 
-	if self.Methods[method] != true {
+	if self.Method != method {
 		return nil
 	}
 
-	if len(components) < self.LengthWithoutOptional || len(components) > self.Length {
+	if len(components) < self.lengthWithoutOptional || len(components) > self.length {
 		return nil
 	}
 
 	mapping := map[string]string{}
 
-	for i, c := range self.Components {
+	for i, c := range self.components {
 		if componentsIsOptional.MatchString(c) {
 			break
 		}
@@ -72,44 +72,31 @@ func (self *Route) Match(method string, components []string) *Match {
 }
 
 func (self *Route) Execute(request *Request) (Response, error) {
-	code := self.Executors[request.Method]
-	return code(request)
+	return self.Code(request)
 }
 
-func MakeRoute(path string, method string, code fn) Route {
+func (self *Route) init() {
 
-	components := []string{}
+	self.components = []string{}
 
-	for _, c := range strings.Split(path, "/") {
-		components = append(components, c)
+	for _, c := range strings.Split(self.Path, "/") {
+		self.components = append(self.components, c)
 	}
+	self.length = len(self.components)
 
-	reqComponents, optComponents := getNamedComponents(components)
-	exec := fns{method: code}
-
-	route := Route{
-		Path:                    path,
-		Executors:               exec,
-		Components:              components,
-		RequiredNamedComponents: reqComponents,
-		OptionalNamedComponents: optComponents,
-		Length:                  len(components),
-		LengthWithoutOptional:   len(components) - len(optComponents),
-		Methods:                 map[string]bool{method: true},
-	}
-
-	return route
+	self.getNamedComponents()
 }
 
-func getNamedComponents(components []string) (map[string]bool, map[string]bool) {
-	reqComponents := map[string]bool{}
-	optComponents := map[string]bool{}
-	for _, c := range components {
+func (self *Route) getNamedComponents() {
+	self.requiredNamedComponents = map[string]bool{}
+	self.optionalNamedComponents = map[string]bool{}
+
+	for _, c := range self.components {
 		if namedComponentsRegex.MatchString(c) == true {
-			reqComponents[c] = true
+			self.requiredNamedComponents[c] = true
 		} else if componentsIsOptional.MatchString(c) == true {
-			optComponents[c] = true
+			self.optionalNamedComponents[c] = true
 		}
 	}
-	return reqComponents, optComponents
+	self.lengthWithoutOptional = self.length - len(self.optionalNamedComponents)
 }
diff --git a/router_test.go b/router_test.go
index 497f547..bc6bc0c 100644
--- a/router_test.go
+++ b/router_test.go
@@ -14,9 +14,9 @@ func testRoute(req *Request) (Response, error) {
 
 func TestBasic(t *testing.T) {
 	router := BuildDispatcher()
-	router.AddRoute("/", "GET", testRoute)
-	router.AddRoute("/blog/:year/:month/:day", "GET", testRoute)
-	router.AddRoute("/blog", "GET", testRoute)
+	router.AddRoute(&Route{Method: "GET", Path: "/", Code: testRoute})
+	router.AddRoute(&Route{Method: "GET", Path: "/blog/:year/:month/:day", Code: testRoute})
+	router.AddRoute(&Route{Method: "GET", Path: "/blog", Code: testRoute})
 
 	if router.Routes[0].Path != "/" {
 		t.Fatal()
@@ -31,8 +31,8 @@ func TestBasic(t *testing.T) {
 
 func TestMatch(t *testing.T) {
 	router := BuildDispatcher()
-	router.AddRoute("/blog/:year/:month/:day", "GET", testRoute)
-	router.AddRoute("/blog", "GET", testRoute)
+	router.AddRoute(&Route{Method: "GET", Path: "/blog/:year/:month/:day", Code: testRoute})
+	router.AddRoute(&Route{Method: "GET", Path: "/blog", Code: testRoute})
 
 	pathToTests := []url.URL{
 		url.URL{Path: "/blog"},
@@ -53,8 +53,8 @@ func TestMatch(t *testing.T) {
 
 func TestMatchOptional(t *testing.T) {
 	router := BuildDispatcher()
-	router.AddRoute("/blog/?:year", "GET", testRoute)
-	router.AddRoute("/blog/:year/?:month", "GET", testRoute)
+	router.AddRoute(&Route{Path: "/blog/?:year", Method: "GET", Code: testRoute})
+	router.AddRoute(&Route{Path: "/blog/:year/?:month", Method: "GET", Code: testRoute})
 
 	pathToTests := []url.URL{
 		url.URL{Path: "/blog"},
@@ -75,8 +75,8 @@ func TestMatchOptional(t *testing.T) {
 
 func TestAmbigiousSimple(t *testing.T) {
 	router := BuildDispatcher()
-	router.AddRoute("/foo/bar", "GET", testRoute)
-	router.AddRoute("/foo/:bar", "GET", testRoute)
+	router.AddRoute(&Route{Path: "/foo/bar", Method: "GET", Code: testRoute})
+	router.AddRoute(&Route{Path: "/foo/:bar", Method: "GET", Code: testRoute})
 
 	r := &http.Request{Method: "GET", URL: &url.URL{Path: "/foo/bar"}}
 	m, _ := router.Match(r)
@@ -89,8 +89,8 @@ func TestAmbigiousSimple(t *testing.T) {
 
 func TestAmbigiousFail(t *testing.T) {
 	router := BuildDispatcher()
-	router.AddRoute("/foo/:bar", "GET", testRoute)
-	router.AddRoute("/:foo/bar", "GET", testRoute)
+	router.AddRoute(&Route{Path: "/foo/:bar", Method: "GET", Code: testRoute})
+	router.AddRoute(&Route{Path: "/:foo/bar", Method: "GET", Code: testRoute})
 
 	r := &http.Request{Method: "GET", URL: &url.URL{Path: "/foo/bar"}}
 	m, err := router.Match(r)