mirror of
https://github.com/metosin/reitit.git
synced 2025-12-23 02:41:10 +00:00
Start working on cljs trie
This commit is contained in:
parent
fbf2786093
commit
cecd6cf526
7 changed files with 63 additions and 51 deletions
|
|
@ -258,10 +258,6 @@ public class Trie {
|
||||||
return matcher.match(0, path.length(), path.toCharArray(), new Match());
|
return matcher.match(0, path.length(), path.toCharArray(), new Match());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matcher scanner(List<Matcher> matchers) {
|
|
||||||
return new LinearMatcher(matchers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Matcher matcher =
|
Matcher matcher =
|
||||||
linearMatcher(
|
linearMatcher(
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@
|
||||||
[[] {}]
|
[[] {}]
|
||||||
compiled-routes)
|
compiled-routes)
|
||||||
lookup (impl/fast-map nl)
|
lookup (impl/fast-map nl)
|
||||||
scanner (trie/scanner pl)
|
matcher (trie/linear-matcher pl)
|
||||||
routes (impl/uncompile-routes compiled-routes)]
|
routes (impl/uncompile-routes compiled-routes)]
|
||||||
^{:type ::router}
|
^{:type ::router}
|
||||||
(reify
|
(reify
|
||||||
|
|
@ -131,7 +131,7 @@
|
||||||
(route-names [_]
|
(route-names [_]
|
||||||
names)
|
names)
|
||||||
(match-by-path [_ path]
|
(match-by-path [_ path]
|
||||||
(if-let [match (trie/lookup scanner path)]
|
(if-let [match (trie/lookup matcher path)]
|
||||||
(-> (:data match)
|
(-> (:data match)
|
||||||
(assoc :path-params (:path-params match))
|
(assoc :path-params (:path-params match))
|
||||||
(assoc :path path))))
|
(assoc :path path))))
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,10 @@
|
||||||
(java.util HashMap Map)
|
(java.util HashMap Map)
|
||||||
(java.net URLEncoder URLDecoder))))
|
(java.net URLEncoder URLDecoder))))
|
||||||
|
|
||||||
(defn normalize [s]
|
|
||||||
(-> s (trie/split-path) (trie/join-path)))
|
|
||||||
|
|
||||||
(defrecord Route [path path-parts path-params])
|
(defrecord Route [path path-parts path-params])
|
||||||
|
|
||||||
(defn parse [path]
|
(defn parse [path]
|
||||||
(let [path #?(:clj (.intern ^String (normalize path)) :cljs (normalize path))
|
(let [path #?(:clj (.intern ^String (trie/normalize path)) :cljs (trie/normalize path))
|
||||||
path-parts (trie/split-path path)
|
path-parts (trie/split-path path)
|
||||||
path-params (->> path-parts (remove string?) (map :value) set)]
|
path-params (->> path-parts (remove string?) (map :value) set)]
|
||||||
(map->Route {:path-params path-params
|
(map->Route {:path-params path-params
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@
|
||||||
(defn wild? [x] (instance? Wild x))
|
(defn wild? [x] (instance? Wild x))
|
||||||
(defn catch-all? [x] (instance? CatchAll x))
|
(defn catch-all? [x] (instance? CatchAll x))
|
||||||
|
|
||||||
|
(defprotocol Matcher
|
||||||
|
(match [this i max path match]))
|
||||||
|
|
||||||
;; https://stackoverflow.com/questions/8033655/find-longest-common-prefix
|
;; https://stackoverflow.com/questions/8033655/find-longest-common-prefix
|
||||||
(defn common-prefix [s1 s2]
|
(defn common-prefix [s1 s2]
|
||||||
(let [max (min (count s1) (count s2))]
|
(let [max (min (count s1) (count s2))]
|
||||||
|
|
@ -58,6 +61,9 @@
|
||||||
(instance? CatchAll x) (str "{*" (-> x :value str (subs 1)) "}"))))
|
(instance? CatchAll x) (str "{*" (-> x :value str (subs 1)) "}"))))
|
||||||
"" xs))
|
"" xs))
|
||||||
|
|
||||||
|
(defn normalize [s]
|
||||||
|
(-> s (split-path) (join-path)))
|
||||||
|
|
||||||
(defn- -node [m]
|
(defn- -node [m]
|
||||||
(map->Node (merge {:children {}, :wilds {}, :catch-all {}} m)))
|
(map->Node (merge {:children {}, :wilds {}, :catch-all {}} m)))
|
||||||
|
|
||||||
|
|
@ -103,6 +109,21 @@
|
||||||
(update :children dissoc ""))
|
(update :children dissoc ""))
|
||||||
node')))
|
node')))
|
||||||
|
|
||||||
|
(defn data-matcher [data]
|
||||||
|
#?(:clj (Trie/dataMatcher data)))
|
||||||
|
|
||||||
|
(defn static-matcher [path matcher]
|
||||||
|
#?(:clj (Trie/staticMatcher path matcher)))
|
||||||
|
|
||||||
|
(defn wild-matcher [path matcher]
|
||||||
|
#?(:clj (Trie/wildMatcher path matcher)))
|
||||||
|
|
||||||
|
(defn catch-all-matcher [path data]
|
||||||
|
#?(:clj (Trie/catchAllMatcher path data)))
|
||||||
|
|
||||||
|
(defn linear-matcher [matchers]
|
||||||
|
#?(:clj (Trie/linearMatcher matchers)))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; public api
|
;; public api
|
||||||
;;
|
;;
|
||||||
|
|
@ -118,14 +139,14 @@
|
||||||
([node path data]
|
([node path data]
|
||||||
(-insert (or node (-node {})) (split-path path) data)))
|
(-insert (or node (-node {})) (split-path path) data)))
|
||||||
|
|
||||||
(defn ^Trie$Matcher compile [{:keys [data children wilds catch-all]}]
|
(defn compile [{:keys [data children wilds catch-all]}]
|
||||||
(let [matchers (cond-> []
|
(let [matchers (cond-> []
|
||||||
data (conj (Trie/dataMatcher data))
|
data (conj (data-matcher data))
|
||||||
children (into (for [[p c] children] (Trie/staticMatcher p (compile c))))
|
children (into (for [[p c] children] (static-matcher p (compile c))))
|
||||||
wilds (into (for [[p c] wilds] (Trie/wildMatcher p (compile c))))
|
wilds (into (for [[p c] wilds] (wild-matcher p (compile c))))
|
||||||
catch-all (into (for [[p c] catch-all] (Trie/catchAllMatcher p (:data c)))))]
|
catch-all (into (for [[p c] catch-all] (catch-all-matcher p (:data c)))))]
|
||||||
(if (rest matchers)
|
(if (rest matchers)
|
||||||
(Trie/linearMatcher matchers)
|
(linear-matcher matchers)
|
||||||
(first matchers))))
|
(first matchers))))
|
||||||
|
|
||||||
(defn pretty [matcher]
|
(defn pretty [matcher]
|
||||||
|
|
@ -135,9 +156,6 @@
|
||||||
(if-let [match ^Trie$Match (Trie/lookup matcher ^String path)]
|
(if-let [match ^Trie$Match (Trie/lookup matcher ^String path)]
|
||||||
(->Match (.data match) (.parameters match))))
|
(->Match (.data match) (.parameters match))))
|
||||||
|
|
||||||
(defn scanner [compiled-tries]
|
|
||||||
(Trie/scanner compiled-tries))
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; spike
|
;; spike
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[reitit.coercion :as coercion]))
|
[reitit.coercion :as coercion]
|
||||||
|
[reitit.trie :as trie]))
|
||||||
|
|
||||||
(s/def ::id (s/or :keyword keyword? :set (s/coll-of keyword? :into #{})))
|
(s/def ::id (s/or :keyword keyword? :set (s/coll-of keyword? :into #{})))
|
||||||
(s/def ::no-doc boolean?)
|
(s/def ::no-doc boolean?)
|
||||||
|
|
@ -65,7 +66,7 @@
|
||||||
:spec ::spec})
|
:spec ::spec})
|
||||||
|
|
||||||
(defn- swagger-path [path]
|
(defn- swagger-path [path]
|
||||||
(-> path impl/normalize (str/replace #"\{\*" "{")))
|
(-> path trie/normalize (str/replace #"\{\*" "{")))
|
||||||
|
|
||||||
(defn create-swagger-handler []
|
(defn create-swagger-handler []
|
||||||
"Create a ring handler to emit swagger spec. Collects all routes from router which have
|
"Create a ring handler to emit swagger spec. Collects all routes from router which have
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,6 @@
|
||||||
(:require [clojure.test :refer [deftest testing is are]]
|
(:require [clojure.test :refer [deftest testing is are]]
|
||||||
[reitit.impl :as impl]))
|
[reitit.impl :as impl]))
|
||||||
|
|
||||||
(deftest normalize-test
|
|
||||||
(are [path expected]
|
|
||||||
(is (= expected (impl/normalize path)))
|
|
||||||
|
|
||||||
"/olipa/:kerran/avaruus", "/olipa/{kerran}/avaruus"
|
|
||||||
"/olipa/{kerran}/avaruus", "/olipa/{kerran}/avaruus"
|
|
||||||
"/olipa/{a.b/c}/avaruus", "/olipa/{a.b/c}/avaruus"
|
|
||||||
"/olipa/kerran/*avaruus", "/olipa/kerran/{*avaruus}"
|
|
||||||
"/olipa/kerran/{*avaruus}", "/olipa/kerran/{*avaruus}"
|
|
||||||
"/olipa/kerran/{*valvavan.suuri/avaruus}", "/olipa/kerran/{*valvavan.suuri/avaruus}"))
|
|
||||||
|
|
||||||
(deftest conflicting-route-test
|
(deftest conflicting-route-test
|
||||||
(are [c? p1 p2]
|
(are [c? p1 p2]
|
||||||
(is (= c? (impl/conflicting-routes? [p1] [p2])))
|
(is (= c? (impl/conflicting-routes? [p1] [p2])))
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,37 @@
|
||||||
(ns reitit.trie-test
|
(ns reitit.trie-test
|
||||||
(:require [clojure.test :refer [deftest testing is are]]
|
(:require [clojure.test :refer [deftest testing is are]]
|
||||||
[reitit.trie :as rt]))
|
[reitit.trie :as trie]))
|
||||||
|
|
||||||
|
(deftest normalize-test
|
||||||
|
(are [path expected]
|
||||||
|
(is (= expected (trie/normalize path)))
|
||||||
|
|
||||||
|
"/olipa/:kerran/avaruus", "/olipa/{kerran}/avaruus"
|
||||||
|
"/olipa/{kerran}/avaruus", "/olipa/{kerran}/avaruus"
|
||||||
|
"/olipa/{a.b/c}/avaruus", "/olipa/{a.b/c}/avaruus"
|
||||||
|
"/olipa/kerran/*avaruus", "/olipa/kerran/{*avaruus}"
|
||||||
|
"/olipa/kerran/{*avaruus}", "/olipa/kerran/{*avaruus}"
|
||||||
|
"/olipa/kerran/{*valvavan.suuri/avaruus}", "/olipa/kerran/{*valvavan.suuri/avaruus}"))
|
||||||
|
|
||||||
(deftest tests
|
(deftest tests
|
||||||
(is (= (rt/->Match {:a 1} {})
|
(is (= (trie/->Match {:a 1} {})
|
||||||
(-> (rt/insert nil "/foo" {:a 1})
|
(-> (trie/insert nil "/foo" {:a 1})
|
||||||
(rt/compile)
|
(trie/compile)
|
||||||
(rt/lookup "/foo"))))
|
(trie/lookup "/foo"))))
|
||||||
|
|
||||||
(is (= (rt/->Match {:a 1} {})
|
(is (= (trie/->Match {:a 1} {})
|
||||||
(-> (rt/insert nil "/foo" {:a 1})
|
(-> (trie/insert nil "/foo" {:a 1})
|
||||||
(rt/insert "/foo/*bar" {:b 1})
|
(trie/insert "/foo/*bar" {:b 1})
|
||||||
(rt/compile)
|
(trie/compile)
|
||||||
(rt/lookup "/foo"))))
|
(trie/lookup "/foo"))))
|
||||||
|
|
||||||
(is (= (rt/->Match {:b 1} {:bar "bar"})
|
(is (= (trie/->Match {:b 1} {:bar "bar"})
|
||||||
(-> (rt/insert nil "/foo" {:a 1})
|
(-> (trie/insert nil "/foo" {:a 1})
|
||||||
(rt/insert "/foo/*bar" {:b 1})
|
(trie/insert "/foo/*bar" {:b 1})
|
||||||
(rt/compile)
|
(trie/compile)
|
||||||
(rt/lookup "/foo/bar"))))
|
(trie/lookup "/foo/bar"))))
|
||||||
|
|
||||||
(is (= (rt/->Match {:a 1} {})
|
(is (= (trie/->Match {:a 1} {})
|
||||||
(-> (rt/insert nil "" {:a 1})
|
(-> (trie/insert nil "" {:a 1})
|
||||||
(rt/compile)
|
(trie/compile)
|
||||||
(rt/lookup "")))))
|
(trie/lookup "")))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue