mirror of
https://github.com/metosin/reitit.git
synced 2025-12-22 10:31:12 +00:00
Initial take on IntoString
This commit is contained in:
parent
5da599ac5b
commit
5ef30443ef
4 changed files with 90 additions and 7 deletions
|
|
@ -175,7 +175,7 @@
|
||||||
(match nil)))
|
(match nil)))
|
||||||
(match-by-name [_ name path-params]
|
(match-by-name [_ name path-params]
|
||||||
(if-let [match (impl/fast-get lookup name)]
|
(if-let [match (impl/fast-get lookup name)]
|
||||||
(match path-params)))))))
|
(match (impl/path-params path-params))))))))
|
||||||
|
|
||||||
(defn lookup-router
|
(defn lookup-router
|
||||||
"Creates a lookup-router from resolved routes and optional
|
"Creates a lookup-router from resolved routes and optional
|
||||||
|
|
@ -215,7 +215,7 @@
|
||||||
(match nil)))
|
(match nil)))
|
||||||
(match-by-name [_ name path-params]
|
(match-by-name [_ name path-params]
|
||||||
(if-let [match (impl/fast-get lookup name)]
|
(if-let [match (impl/fast-get lookup name)]
|
||||||
(match path-params)))))))
|
(match (impl/path-params path-params))))))))
|
||||||
|
|
||||||
(defn segment-router
|
(defn segment-router
|
||||||
"Creates a special prefix-tree style segment router from resolved routes and optional
|
"Creates a special prefix-tree style segment router from resolved routes and optional
|
||||||
|
|
@ -255,7 +255,7 @@
|
||||||
(match nil)))
|
(match nil)))
|
||||||
(match-by-name [_ name path-params]
|
(match-by-name [_ name path-params]
|
||||||
(if-let [match (impl/fast-get lookup name)]
|
(if-let [match (impl/fast-get lookup name)]
|
||||||
(match path-params)))))))
|
(match (impl/path-params path-params))))))))
|
||||||
|
|
||||||
(defn single-static-path-router
|
(defn single-static-path-router
|
||||||
"Creates a fast router of 1 static route(s) and optional
|
"Creates a fast router of 1 static route(s) and optional
|
||||||
|
|
@ -290,7 +290,7 @@
|
||||||
match))
|
match))
|
||||||
(match-by-name [_ name path-params]
|
(match-by-name [_ name path-params]
|
||||||
(if (= n name)
|
(if (= n name)
|
||||||
(impl/fast-assoc match :path-params path-params)))))))
|
(impl/fast-assoc match :path-params (impl/path-params path-params))))))))
|
||||||
|
|
||||||
(defn mixed-router
|
(defn mixed-router
|
||||||
"Creates two routers: [[lookup-router]] or [[single-static-path-router]] for
|
"Creates two routers: [[lookup-router]] or [[single-static-path-router]] for
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,10 @@
|
||||||
(ns ^:no-doc reitit.impl
|
(ns ^:no-doc reitit.impl
|
||||||
(:require [clojure.string :as str]
|
(:require [clojure.string :as str]
|
||||||
[clojure.set :as set])
|
[clojure.set :as set])
|
||||||
#?(:clj (:import (java.util.regex Pattern)
|
#?(:clj
|
||||||
(java.util HashMap Map))))
|
(:import (java.util.regex Pattern)
|
||||||
|
(java.util HashMap Map)
|
||||||
|
(java.net URLEncoder URLDecoder))))
|
||||||
|
|
||||||
(defn wild? [s]
|
(defn wild? [s]
|
||||||
(contains? #{\: \*} (first (str s))))
|
(contains? #{\: \*} (first (str s))))
|
||||||
|
|
@ -135,7 +137,7 @@
|
||||||
(defn throw-on-missing-path-params [template required path-params]
|
(defn throw-on-missing-path-params [template required path-params]
|
||||||
(when-not (every? #(contains? path-params %) required)
|
(when-not (every? #(contains? path-params %) required)
|
||||||
(let [defined (-> path-params keys set)
|
(let [defined (-> path-params keys set)
|
||||||
missing (clojure.set/difference required defined)]
|
missing (set/difference required defined)]
|
||||||
(throw
|
(throw
|
||||||
(ex-info
|
(ex-info
|
||||||
(str "missing path-params for route " template " -> " missing)
|
(str "missing path-params for route " template " -> " missing)
|
||||||
|
|
@ -155,3 +157,50 @@
|
||||||
|
|
||||||
(defn strip-nils [m]
|
(defn strip-nils [m]
|
||||||
(->> m (remove (comp nil? second)) (into {})))
|
(->> m (remove (comp nil? second)) (into {})))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Path-parameters, see https://github.com/metosin/reitit/issues/75
|
||||||
|
;;
|
||||||
|
|
||||||
|
(defn url-encode [s]
|
||||||
|
(some-> s
|
||||||
|
#?(:clj (URLEncoder/encode "UTF-8")
|
||||||
|
:cljs (js/encodeURIComponent))
|
||||||
|
(.replace "+" "%20")))
|
||||||
|
|
||||||
|
(defn url-decode [s]
|
||||||
|
#?(:clj (some-> s (URLDecoder/decode "UTF-8"))
|
||||||
|
:cljs (some-> s (js/decodeURIComponent))))
|
||||||
|
|
||||||
|
(defprotocol IntoString
|
||||||
|
(into-string [_]))
|
||||||
|
|
||||||
|
(extend-protocol IntoString
|
||||||
|
#?(:clj String
|
||||||
|
:cljs string)
|
||||||
|
(into-string [this] this)
|
||||||
|
|
||||||
|
#?(:clj clojure.lang.Keyword
|
||||||
|
:cljs cljs.core.Keyword)
|
||||||
|
(into-string [this]
|
||||||
|
(str (namespace this)
|
||||||
|
(when (namespace this) "/")
|
||||||
|
(name this)))
|
||||||
|
|
||||||
|
#?(:clj Number
|
||||||
|
:cljs number)
|
||||||
|
(into-string [this] (str this))
|
||||||
|
|
||||||
|
#?(:clj Object
|
||||||
|
:cljs object)
|
||||||
|
(into-string [this] (str this)))
|
||||||
|
|
||||||
|
(defn path-params
|
||||||
|
"shallow transform of the path-param values into strings"
|
||||||
|
[params]
|
||||||
|
(persistent!
|
||||||
|
(reduce-kv
|
||||||
|
(fn [m k v]
|
||||||
|
(assoc! m k (url-encode (into-string v))))
|
||||||
|
(transient {})
|
||||||
|
params)))
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,12 @@
|
||||||
:path "/api/ipa/large"
|
:path "/api/ipa/large"
|
||||||
:path-params {:size "large"}})
|
:path-params {:size "large"}})
|
||||||
(r/match-by-name router ::beer {:size "large"})))
|
(r/match-by-name router ::beer {:size "large"})))
|
||||||
|
(is (= (r/map->Match
|
||||||
|
{:template "/api/ipa/:size"
|
||||||
|
:data {:name ::beer}
|
||||||
|
:path "/api/ipa/large"
|
||||||
|
:path-params {:size "large"}})
|
||||||
|
(r/match-by-name router ::beer {:size :large})))
|
||||||
(is (= nil (r/match-by-name router "ILLEGAL")))
|
(is (= nil (r/match-by-name router "ILLEGAL")))
|
||||||
(is (= [::beer] (r/route-names router)))
|
(is (= [::beer] (r/route-names router)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,31 @@
|
||||||
|
|
||||||
(deftest strip-nils-test
|
(deftest strip-nils-test
|
||||||
(is (= {:a 1, :c false} (impl/strip-nils {:a 1, :b nil, :c false}))))
|
(is (= {:a 1, :c false} (impl/strip-nils {:a 1, :b nil, :c false}))))
|
||||||
|
|
||||||
|
(deftest into-string-test
|
||||||
|
(is (= "1" (impl/into-string 1)))
|
||||||
|
(is (= "2.2" (impl/into-string 2.2)))
|
||||||
|
(is (= "kikka" (impl/into-string "kikka")))
|
||||||
|
(is (= "kikka" (impl/into-string :kikka)))
|
||||||
|
(is (= "reitit.impl-test/kikka" (impl/into-string ::kikka))))
|
||||||
|
|
||||||
|
(deftest url-encode-and-decode-test
|
||||||
|
(is (= "reitit.impl-test%2Fkikka" (-> ::kikka
|
||||||
|
impl/into-string
|
||||||
|
impl/url-encode)))
|
||||||
|
(is (= "reitit.impl-test/kikka" (-> ::kikka
|
||||||
|
impl/into-string
|
||||||
|
impl/url-encode
|
||||||
|
impl/url-decode))))
|
||||||
|
|
||||||
|
(deftest path-params-test
|
||||||
|
(is (= {:n "1"
|
||||||
|
:d "2.2"
|
||||||
|
:s "kikka"
|
||||||
|
:k "kikka"
|
||||||
|
:qk "reitit.impl-test%2Fkikka"}
|
||||||
|
(impl/path-params {:n 1
|
||||||
|
:d 2.2
|
||||||
|
:s "kikka"
|
||||||
|
:k :kikka
|
||||||
|
:qk ::kikka}))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue