mirror of
https://github.com/metosin/reitit.git
synced 2025-12-23 10: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());
|
||||
}
|
||||
|
||||
public static Matcher scanner(List<Matcher> matchers) {
|
||||
return new LinearMatcher(matchers);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Matcher matcher =
|
||||
linearMatcher(
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@
|
|||
[[] {}]
|
||||
compiled-routes)
|
||||
lookup (impl/fast-map nl)
|
||||
scanner (trie/scanner pl)
|
||||
matcher (trie/linear-matcher pl)
|
||||
routes (impl/uncompile-routes compiled-routes)]
|
||||
^{:type ::router}
|
||||
(reify
|
||||
|
|
@ -131,7 +131,7 @@
|
|||
(route-names [_]
|
||||
names)
|
||||
(match-by-path [_ path]
|
||||
(if-let [match (trie/lookup scanner path)]
|
||||
(if-let [match (trie/lookup matcher path)]
|
||||
(-> (:data match)
|
||||
(assoc :path-params (:path-params match))
|
||||
(assoc :path path))))
|
||||
|
|
|
|||
|
|
@ -9,13 +9,10 @@
|
|||
(java.util HashMap Map)
|
||||
(java.net URLEncoder URLDecoder))))
|
||||
|
||||
(defn normalize [s]
|
||||
(-> s (trie/split-path) (trie/join-path)))
|
||||
|
||||
(defrecord Route [path path-parts path-params])
|
||||
|
||||
(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-params (->> path-parts (remove string?) (map :value) set)]
|
||||
(map->Route {:path-params path-params
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
(defn wild? [x] (instance? Wild 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
|
||||
(defn common-prefix [s1 s2]
|
||||
(let [max (min (count s1) (count s2))]
|
||||
|
|
@ -58,6 +61,9 @@
|
|||
(instance? CatchAll x) (str "{*" (-> x :value str (subs 1)) "}"))))
|
||||
"" xs))
|
||||
|
||||
(defn normalize [s]
|
||||
(-> s (split-path) (join-path)))
|
||||
|
||||
(defn- -node [m]
|
||||
(map->Node (merge {:children {}, :wilds {}, :catch-all {}} m)))
|
||||
|
||||
|
|
@ -103,6 +109,21 @@
|
|||
(update :children dissoc ""))
|
||||
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
|
||||
;;
|
||||
|
|
@ -118,14 +139,14 @@
|
|||
([node 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-> []
|
||||
data (conj (Trie/dataMatcher data))
|
||||
children (into (for [[p c] children] (Trie/staticMatcher p (compile c))))
|
||||
wilds (into (for [[p c] wilds] (Trie/wildMatcher p (compile c))))
|
||||
catch-all (into (for [[p c] catch-all] (Trie/catchAllMatcher p (:data c)))))]
|
||||
data (conj (data-matcher data))
|
||||
children (into (for [[p c] children] (static-matcher p (compile c))))
|
||||
wilds (into (for [[p c] wilds] (wild-matcher p (compile c))))
|
||||
catch-all (into (for [[p c] catch-all] (catch-all-matcher p (:data c)))))]
|
||||
(if (rest matchers)
|
||||
(Trie/linearMatcher matchers)
|
||||
(linear-matcher matchers)
|
||||
(first matchers))))
|
||||
|
||||
(defn pretty [matcher]
|
||||
|
|
@ -135,9 +156,6 @@
|
|||
(if-let [match ^Trie$Match (Trie/lookup matcher ^String path)]
|
||||
(->Match (.data match) (.parameters match))))
|
||||
|
||||
(defn scanner [compiled-tries]
|
||||
(Trie/scanner compiled-tries))
|
||||
|
||||
;;
|
||||
;; spike
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
[clojure.spec.alpha :as s]
|
||||
[clojure.set :as set]
|
||||
[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 ::no-doc boolean?)
|
||||
|
|
@ -65,7 +66,7 @@
|
|||
:spec ::spec})
|
||||
|
||||
(defn- swagger-path [path]
|
||||
(-> path impl/normalize (str/replace #"\{\*" "{")))
|
||||
(-> path trie/normalize (str/replace #"\{\*" "{")))
|
||||
|
||||
(defn create-swagger-handler []
|
||||
"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]]
|
||||
[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
|
||||
(are [c? p1 p2]
|
||||
(is (= c? (impl/conflicting-routes? [p1] [p2])))
|
||||
|
|
|
|||
|
|
@ -1,26 +1,37 @@
|
|||
(ns reitit.trie-test
|
||||
(: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
|
||||
(is (= (rt/->Match {:a 1} {})
|
||||
(-> (rt/insert nil "/foo" {:a 1})
|
||||
(rt/compile)
|
||||
(rt/lookup "/foo"))))
|
||||
(is (= (trie/->Match {:a 1} {})
|
||||
(-> (trie/insert nil "/foo" {:a 1})
|
||||
(trie/compile)
|
||||
(trie/lookup "/foo"))))
|
||||
|
||||
(is (= (rt/->Match {:a 1} {})
|
||||
(-> (rt/insert nil "/foo" {:a 1})
|
||||
(rt/insert "/foo/*bar" {:b 1})
|
||||
(rt/compile)
|
||||
(rt/lookup "/foo"))))
|
||||
(is (= (trie/->Match {:a 1} {})
|
||||
(-> (trie/insert nil "/foo" {:a 1})
|
||||
(trie/insert "/foo/*bar" {:b 1})
|
||||
(trie/compile)
|
||||
(trie/lookup "/foo"))))
|
||||
|
||||
(is (= (rt/->Match {:b 1} {:bar "bar"})
|
||||
(-> (rt/insert nil "/foo" {:a 1})
|
||||
(rt/insert "/foo/*bar" {:b 1})
|
||||
(rt/compile)
|
||||
(rt/lookup "/foo/bar"))))
|
||||
(is (= (trie/->Match {:b 1} {:bar "bar"})
|
||||
(-> (trie/insert nil "/foo" {:a 1})
|
||||
(trie/insert "/foo/*bar" {:b 1})
|
||||
(trie/compile)
|
||||
(trie/lookup "/foo/bar"))))
|
||||
|
||||
(is (= (rt/->Match {:a 1} {})
|
||||
(-> (rt/insert nil "" {:a 1})
|
||||
(rt/compile)
|
||||
(rt/lookup "")))))
|
||||
(is (= (trie/->Match {:a 1} {})
|
||||
(-> (trie/insert nil "" {:a 1})
|
||||
(trie/compile)
|
||||
(trie/lookup "")))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue