about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--dispatcher.go6
-rw-r--r--route.go73
2 files changed, 60 insertions, 19 deletions
diff --git a/dispatcher.go b/dispatcher.go
index b40b556..987f182 100644
--- a/dispatcher.go
+++ b/dispatcher.go
@@ -35,9 +35,9 @@ func (self *Dispatcher) AddRoute(path string, method string, code func(*Request)
 
 func (self *Dispatcher) Match(request Request) *Route {
 	for _, r := range self.Routes {
-		match, route := r.Match(request)
-		if match == true {
-			return route
+		match := r.Match(request)
+		if match != nil {
+			return match.Route
 		}
 	}
 	return nil
diff --git a/route.go b/route.go
index 0c397f3..9996f5c 100644
--- a/route.go
+++ b/route.go
@@ -1,18 +1,32 @@
 package mooh
 
 import (
+	"regexp"
 	"strings"
 )
 
+type fn map[string]func(*Request) (Response, error)
+
 type Route struct {
-	Path       string
-	Executors  map[string]func(*Request) (Response, error)
-	Components []string
-	Length     int
-	//TODO validator
+	Path                    string
+	Executors               fn
+	Components              []string
+	RequiredNamedComponents map[string]bool
+	OptionalNamedComponents map[string]bool
+	Length                  int
+}
+
+type Match struct {
+	Path    string
+	Route   *Route
+	Mapping map[string]string
+	Method  string
 }
 
-func (self *Route) Match(request Request) (bool, *Route) {
+var componentIsVariable = regexp.MustCompile("^:")
+var namedComponentsRegex = regexp.MustCompile("^:(.*)$")
+
+func (self *Route) Match(request Request) *Match {
 
 	methodMatch := false
 	for m, _ := range self.Executors {
@@ -21,22 +35,37 @@ func (self *Route) Match(request Request) (bool, *Route) {
 		}
 	}
 	if methodMatch == false {
-		return false, nil
+		return nil
 	}
 
 	components := strings.Split(request.Request.URL.Path, "/")
 
 	if len(components) > self.Length {
-		return false, nil
+		return nil
 	}
 
+	mapping := map[string]string{}
+
 	for i, c := range self.Components {
 		p := components[i]
-		if p != c {
-			return false, nil
+
+		if componentIsVariable.MatchString(c) == true {
+			mapping[c] = p
+		} else {
+			if p != c {
+				return nil
+			}
 		}
 	}
-	return true, self
+
+	match := &Match{
+		Path:    request.Request.URL.Path,
+		Route:   self,
+		Mapping: mapping,
+		Method:  request.Method,
+	}
+
+	return match
 }
 
 func (self *Route) Execute(request *Request) (Response, error) {
@@ -48,14 +77,26 @@ func MakeRoute(path string, method string, code func(*Request) (Response, error)
 
 	components := strings.Split(path, "/")
 
-	exec := map[string]func(*Request) (Response, error){method: code}
+	namedComponents := getNamedComponents(components)
+	exec := fn{method: code}
 
 	route := Route{
-		Path:       path,
-		Executors:  exec,
-		Components: components,
-		Length:     len(components),
+		Path:                    path,
+		Executors:               exec,
+		Components:              components,
+		RequiredNamedComponents: namedComponents,
+		Length:                  len(components),
 	}
 
 	return route
 }
+
+func getNamedComponents(components []string) map[string]bool {
+	namedComponents := map[string]bool{}
+	for _, c := range components {
+		if namedComponentsRegex.MatchString(c) == true {
+			namedComponents[c] = true
+		}
+	}
+	return namedComponents
+}