package mooh import ( "regexp" "strings" ) type fn map[string]func(*Request) (Response, error) type Route struct { 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 } var componentIsVariable = regexp.MustCompile("^:") var namedComponentsRegex = regexp.MustCompile("^:(.*)$") func (self *Route) Match(request Request) *Match { methodMatch := false for m, _ := range self.Executors { if m == request.Method { methodMatch = true } } if methodMatch == false { return nil } components := strings.Split(request.Request.URL.Path, "/") if len(components) > self.Length { return nil } mapping := map[string]string{} for i, c := range self.Components { p := components[i] if componentIsVariable.MatchString(c) == true { mapping[c] = p } else { if p != c { return nil } } } match := &Match{ Path: request.Request.URL.Path, Route: self, Mapping: mapping, Method: request.Method, } return match } func (self *Route) Execute(request *Request) (Response, error) { code := self.Executors[request.Method] return code(request) } func MakeRoute(path string, method string, code func(*Request) (Response, error)) Route { components := strings.Split(path, "/") namedComponents := getNamedComponents(components) exec := fn{method: code} route := Route{ 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 }