diff options
-rw-r--r-- | dispatcher.go | 6 | ||||
-rw-r--r-- | route.go | 73 |
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 +} |