Separate route-data-merge protocol

This commit is contained in:
Juho Teperi 2021-12-26 00:42:29 +02:00
parent 28707fff07
commit d1c9ff638d
6 changed files with 34 additions and 26 deletions

View file

@ -17,8 +17,7 @@
(-open-model [this model] "Returns a new model which allows extra keys in maps") (-open-model [this model] "Returns a new model which allows extra keys in maps")
(-encode-error [this error] "Converts error in to a serializable format") (-encode-error [this error] "Converts error in to a serializable format")
(-request-coercer [this type model] "Returns a `value format => value` request coercion function") (-request-coercer [this type model] "Returns a `value format => value` request coercion function")
(-response-coercer [this model] "Returns a `value format => value` response coercion function") (-response-coercer [this model] "Returns a `value format => value` response coercion function"))
(-route-data-merge [this acc k v]))
#?(:clj #?(:clj
(defmethod print-method ::coercion [coercion ^Writer w] (defmethod print-method ::coercion [coercion ^Writer w]

View file

@ -9,6 +9,9 @@
(:import (java.util HashMap Map) (:import (java.util HashMap Map)
(java.net URLEncoder URLDecoder)))) (java.net URLEncoder URLDecoder))))
(defprotocol RouteDataMerge
(-route-data-merge [this acc k v]))
(defn parse [path opts] (defn parse [path opts]
(let [path #?(:clj (.intern ^String (trie/normalize path opts)) :cljs (trie/normalize path opts)) (let [path #?(:clj (.intern ^String (trie/normalize path opts)) :cljs (trie/normalize path opts))
path-parts (trie/split-path path opts) path-parts (trie/split-path path opts)
@ -67,13 +70,15 @@
(let [;; Find last the effective :coercion value (let [;; Find last the effective :coercion value
;; for the route, and then use the cocercion ;; for the route, and then use the cocercion
;; instance for route data merge implementation. ;; instance for route data merge implementation.
;; TODO: other options/keys should also be able to control
;; merge?
coercion (->> x coercion (->> x
reverse reverse
(some (fn [[k v]] (some (fn [[k v]]
(when (= :coercion k) (when (= :coercion k)
v)))) v))))
route-data-merge (if coercion route-data-merge (if coercion
#((resolve 'reitit.coercion/-route-data-merge) coercion %1 %2 %3) #(-route-data-merge coercion %1 %2 %3)
default-route-data-merge)] default-route-data-merge)]
(reduce (reduce
(fn [acc [k v]] (fn [acc [k v]]
@ -85,8 +90,7 @@
x))) x)))
(defn resolve-routes [raw-routes {:keys [coerce] :as opts}] (defn resolve-routes [raw-routes {:keys [coerce] :as opts}]
(cond->> (->> (walk raw-routes opts) (cond->> (->> (walk raw-routes opts) (map-data merge-data))
(map-data merge-data))
coerce (into [] (keep #(coerce % opts))))) coerce (into [] (keep #(coerce % opts)))))
(defn path-conflicting-routes [routes opts] (defn path-conflicting-routes [routes opts]

View file

@ -8,7 +8,7 @@
[malli.core :as m] [malli.core :as m]
[clojure.set :as set] [clojure.set :as set]
[clojure.walk :as walk] [clojure.walk :as walk]
[meta-merge.core :as mm])) [reitit.impl :as impl]))
;; ;;
;; coercion ;; coercion
@ -181,9 +181,10 @@
(-coercer (compile schema options) type transformers :decode opts)) (-coercer (compile schema options) type transformers :decode opts))
(-response-coercer [_ schema] (-response-coercer [_ schema]
(-coercer (compile schema options) :response transformers :encode opts)) (-coercer (compile schema options) :response transformers :encode opts))
impl/RouteDataMerge
(-route-data-merge [_ acc k v] (-route-data-merge [_ acc k v]
(case k (case k
:parameters (assoc acc :parameters (merge-with mu/merge (:parameters acc) v)) :parameters (assoc acc :parameters (merge-with mu/merge (:parameters acc) v))
(mm/meta-merge acc {k v}))))))) (impl/default-route-data-merge acc k v)))))))
(def coercion (create default-options)) (def coercion (create default-options))

View file

@ -96,6 +96,7 @@
(-response-coercer [this schema] (-response-coercer [this schema]
(if (coerce-response? schema) (if (coerce-response? schema)
(coercion/-request-coercer this :response schema))) (coercion/-request-coercer this :response schema)))
impl/RouteDataMerge
(-route-data-merge [this acc k v] (-route-data-merge [this acc k v]
(impl/default-route-data-merge acc k v)))) (impl/default-route-data-merge acc k v))))

View file

@ -137,6 +137,7 @@
(-response-coercer [this spec] (-response-coercer [this spec]
(if (coerce-response? spec) (if (coerce-response? spec)
(coercion/-request-coercer this :response spec))) (coercion/-request-coercer this :response spec)))
impl/RouteDataMerge
(-route-data-merge [this acc k v] (-route-data-merge [this acc k v]
(impl/default-route-data-merge acc k v)))) (impl/default-route-data-merge acc k v))))

View file

@ -190,14 +190,16 @@
[:view 'b] [:view 'b]
[:controllers ^:replace [2]]]))) [:controllers ^:replace [2]]])))
(testing "Schema - regular merge"
(is (= {:a schema/Str (is (= {:a schema/Str
:b schema/Str} :b schema/Str}
(-> (impl/merge-data "/" (-> (impl/merge-data "/"
[[:parameters {:path {:a schema/Str}}] [[:parameters {:path {:a schema/Str}}]
[:parameters {:path {:b schema/Str}}]]) [:parameters {:path {:b schema/Str}}]])
:parameters :parameters
:path))) :path))))
(testing "Malli schema merge - mu/merge"
(is (= [:map (is (= [:map
[:a 'string?] [:a 'string?]
[:b 'int?]] [:b 'int?]]
@ -208,7 +210,7 @@
:parameters :parameters
:path :path
;; Merge returns schema object, convert back to form for comparison ;; Merge returns schema object, convert back to form for comparison
malli.core/form))) malli.core/form))))
;; TODO: Also test and support Schema and spec merging ;; TODO: Spec
) )