diff --git a/modules/reitit-core/src/reitit/impl.cljc b/modules/reitit-core/src/reitit/impl.cljc index 3607d81b..7bbae117 100644 --- a/modules/reitit-core/src/reitit/impl.cljc +++ b/modules/reitit-core/src/reitit/impl.cljc @@ -29,7 +29,7 @@ (defn catch-all-param [s] (let [ss (str s)] (if (= \* (first ss)) - (keyword ss)))) + (keyword (subs ss 1))))) (defn wild-or-catch-all-param? [x] (boolean (or (wild-param x) (catch-all-param x)))) diff --git a/modules/reitit-core/src/reitit/segment.cljc b/modules/reitit-core/src/reitit/segment.cljc index ac27305f..a418afe0 100644 --- a/modules/reitit-core/src/reitit/segment.cljc +++ b/modules/reitit-core/src/reitit/segment.cljc @@ -1,5 +1,6 @@ (ns reitit.segment - (:require [reitit.impl :as impl])) + (:require [reitit.impl :as impl] + [clojure.string :as str])) (defrecord Match [data params]) @@ -12,41 +13,45 @@ (-insert [this ps data]) (-lookup [this ps params])) -;; TODO: catch-all +(defn- -catch-all [catch-all data params p ps] + (if catch-all + (assoc data :params (assoc params catch-all (str/join "/" (cons p ps)))))) + (defn- segment - ([] - (segment {} #{} nil)) - ([children wilds data] + ([] (segment {} #{} nil nil)) + ([children wilds catch-all data] (let [children' (impl/fast-map children)] + ^{:type ::segment} (reify Segment - (-insert [_ [p & ps] data] + (-insert [_ [p & ps] d] (if-not p - (segment children wilds data) - (let [wild (impl/wild-param p) - wilds (if wild (conj wilds wild) wilds) - children (update children (or wild p) #(-insert (or % (segment)) ps data))] - (segment children wilds nil)))) + (segment children wilds catch-all d) + (let [[w c] ((juxt impl/wild-param impl/catch-all-param) p) + wilds (if w (conj wilds w) wilds) + catch-all (or c catch-all) + children (update children (or w c p) #(-insert (or % (segment)) ps d))] + (segment children wilds catch-all data)))) (-lookup [_ [p & ps] params] (if (nil? p) (if data (assoc data :params params)) (or (-lookup (impl/fast-get children' p) ps params) - (some #(-lookup (impl/fast-get children' %) ps (assoc params % p)) wilds)))))))) + (some #(-lookup (impl/fast-get children' %) ps (assoc params % p)) wilds) + (-catch-all catch-all data params p ps)))))))) (defn create [paths] (reduce (fn [segment [p data]] - (let [ps (impl/segments p)] - (-insert segment ps (map->Match {:data data})))) + (-insert segment (impl/segments p) (map->Match {:data data}))) (segment) paths)) (defn lookup [segment ^String path] - (let [ps (.split path "/")] - (-lookup segment ps {}))) + (-lookup segment (.split path "/") {})) (comment (-> [["/:abba" 1] - ["/kikka/*kakka" 2]] + ["/:abba/:dabba" 2] + ["/kikka/*kakka" 3]] (create) - (lookup "/kikka") + (lookup "/kikka/1/2") (./aprint)))