Initial take on IntoString

This commit is contained in:
Tommi Reiman 2018-03-20 16:30:53 +02:00
parent 5da599ac5b
commit 5ef30443ef
4 changed files with 90 additions and 7 deletions

View file

@ -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

View file

@ -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)))

View file

@ -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)))

View file

@ -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}))))