about summary refs log tree commit diff
path: root/route.go
diff options
context:
space:
mode:
Diffstat (limited to 'route.go')
-rw-r--r--route.go77
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)