summaryrefslogtreecommitdiff
path: root/src/ruuter
diff options
context:
space:
mode:
Diffstat (limited to 'src/ruuter')
-rw-r--r--src/ruuter/core.cljc42
1 files changed, 30 insertions, 12 deletions
diff --git a/src/ruuter/core.cljc b/src/ruuter/core.cljc
index c1c5644..c2e05a1 100644
--- a/src/ruuter/core.cljc
+++ b/src/ruuter/core.cljc
@@ -62,6 +62,18 @@
:wildcard nil ;; {:param-name kw, :leaves [...]} or nil
:leaves []}) ;; routes that terminate here [{:method :get :response fn :path str}]
+(defn- throw-conflict
+ "Throws an exception when two routes define different parameter names at the
+ same trie position."
+ [slot-type existing-name new-name path]
+ (let [msg (str "ruuter: conflicting " slot-type " parameter names at same position — :"
+ (name existing-name) " and :" (name new-name)
+ ". Route: " path)]
+ (throw (ex-info msg {:slot-type slot-type
+ :existing-name existing-name
+ :new-name new-name
+ :path path}))))
+
(defn- insert-route
"Inserts a single route into the trie, returning the updated trie."
[trie segments leaf]
@@ -76,22 +88,28 @@
(assoc-in trie [:children value] child'))
:param
- (let [existing (:param trie)
- child (if existing (:node existing) (empty-node))
- child' (insert-route child remaining leaf)]
- (assoc trie :param {:param-name value :node child'}))
+ (let [existing (:param trie)]
+ (when (and existing (not= (:param-name existing) value))
+ (throw-conflict "param" (:param-name existing) value (:path leaf)))
+ (let [child (if existing (:node existing) (empty-node))
+ child' (insert-route child remaining leaf)]
+ (assoc trie :param {:param-name value :node child'})))
:optional
- (let [existing (:optional trie)
- child (if existing (:node existing) (empty-node))
- child' (insert-route child remaining leaf)]
- (assoc trie :optional {:param-name value :node child'}))
+ (let [existing (:optional trie)]
+ (when (and existing (not= (:param-name existing) value))
+ (throw-conflict "optional" (:param-name existing) value (:path leaf)))
+ (let [child (if existing (:node existing) (empty-node))
+ child' (insert-route child remaining leaf)]
+ (assoc trie :optional {:param-name value :node child'})))
:wildcard
- (let [existing (:wildcard trie)
- leaves (if existing (:leaves existing) [])
- leaves' (conj leaves leaf)]
- (assoc trie :wildcard {:param-name value :leaves leaves'}))))))
+ (let [existing (:wildcard trie)]
+ (when (and existing (not= (:param-name existing) value))
+ (throw-conflict "wildcard" (:param-name existing) value (:path leaf)))
+ (let [leaves (if existing (:leaves existing) [])
+ leaves' (conj leaves leaf)]
+ (assoc trie :wildcard {:param-name value :leaves leaves'})))))))
(defn compile-routes
"Compiles a vector of route maps into a trie structure for efficient