diff options
Diffstat (limited to 'route.go')
-rw-r--r-- | route.go | 77 |
1 files changed, 67 insertions, 10 deletions
diff --git a/route.go b/route.go index b724a04..9eab0ab 100644 --- a/route.go +++ b/route.go @@ -17,6 +17,7 @@ type Route struct { optionalNamedComponents map[string]bool length int lengthWithoutOptional int + Validations map[string]*regexp.Regexp } type Match struct { @@ -31,11 +32,19 @@ var componentsIsOptional = regexp.MustCompile("^\\?:") var namedComponentsRegex = regexp.MustCompile("^:(.*)$") var convertComponent = regexp.MustCompile("^\\??:(.*)$") +// XXX explain this function func (self *Route) convertComponentName(name string) string { newName := convertComponent.FindStringSubmatch(name) + if len(newName) == 0 { + return name + } return newName[1] } +func (self *Route) ValidateFor(key string, component string) bool { + return self.Validations[key].MatchString(component) +} + func (self *Route) Match(method string, components []string) *Match { if self.Method != method { @@ -48,15 +57,35 @@ func (self *Route) Match(method string, components []string) *Match { mapping := map[string]string{} - for i, c := range self.components { - if componentsIsOptional.MatchString(c) { - break - } - p := components[i] + currentComponentsLength := len(components) - if componentIsVariable.MatchString(c) == true { - mapping[self.convertComponentName(c)] = p - } else { +L: + for i, c := range self.components { + convertedName := self.convertComponentName(c) + + switch { + case self.IsOptionalUrlParameter(convertedName) == true: + if i < currentComponentsLength && self.HasValidationFor(convertedName) { + p := components[i] + if self.ValidateFor(convertedName, p) == true { + break L + } + } else { + break L + } + case self.IsRequiredUrlParameter(convertedName) == true: + p := components[i] + if self.HasValidationFor(convertedName) { + if self.ValidateFor(convertedName, p) == true { + mapping[convertedName] = p + } else { + return nil + } + } else { + mapping[convertedName] = p + } + default: + p := components[i] if p != c { return nil } @@ -85,6 +114,34 @@ func (self *Route) init() { self.length = len(self.components) self.getNamedComponents() + + for k, _ := range self.Validations { + if self.IsUrlParameter(k) == false { + panic(k + " is missing") + } + } +} + +func (self *Route) IsUrlParameter(component string) bool { + if self.IsRequiredUrlParameter(component) == false && self.IsOptionalUrlParameter(component) == false { + return false + } + return true +} + +func (self *Route) IsRequiredUrlParameter(component string) bool { + return self.requiredNamedComponents[component] +} + +func (self *Route) IsOptionalUrlParameter(component string) bool { + return self.optionalNamedComponents[component] +} + +func (self *Route) HasValidationFor(component string) bool { + if self.Validations[component] != nil { + return true + } + return false } func (self *Route) getNamedComponents() { @@ -93,9 +150,9 @@ func (self *Route) getNamedComponents() { for _, c := range self.components { if namedComponentsRegex.MatchString(c) == true { - self.requiredNamedComponents[c] = true + self.requiredNamedComponents[self.convertComponentName(c)] = true } else if componentsIsOptional.MatchString(c) == true { - self.optionalNamedComponents[c] = true + self.optionalNamedComponents[self.convertComponentName(c)] = true } } self.lengthWithoutOptional = self.length - len(self.optionalNamedComponents) |