diff --git a/modules/reitit-core/src/reitit/coercion.cljc b/modules/reitit-core/src/reitit/coercion.cljc index 8dd08d83..bc3dc6ca 100644 --- a/modules/reitit-core/src/reitit/coercion.cljc +++ b/modules/reitit-core/src/reitit/coercion.cljc @@ -1,5 +1,5 @@ (ns reitit.coercion - (:require [clojure.walk :as walk] + (:require [#?(:clj reitit.walk :cljs clojure.walk) :as walk] [reitit.impl :as impl]) #?(:clj (:import (java.io Writer)))) diff --git a/modules/reitit-core/src/reitit/walk.clj b/modules/reitit-core/src/reitit/walk.clj new file mode 100644 index 00000000..b8b832fd --- /dev/null +++ b/modules/reitit-core/src/reitit/walk.clj @@ -0,0 +1,52 @@ +(ns ^:no-doc reitit.walk) + +(defprotocol Walkable + (-walk [coll f])) + +(extend-protocol Walkable + nil + (-walk [_ _] nil) + Object + (-walk [x _] x) + clojure.lang.IMapEntry + (-walk [e f] (clojure.lang.MapEntry. (f (.key e)) (f (.val e)))) + clojure.lang.ISeq + (-walk [coll f] (map f coll)) + clojure.lang.PersistentList + (-walk [coll f] (apply list (map f coll))) + clojure.lang.PersistentList$EmptyList + (-walk [x _] x) + clojure.lang.IRecord + (-walk [r f] (reduce (fn [r x] (conj r (f x))) r r))) + +(defn- -walk-default + [coll f] + (into (empty coll) (map f) coll)) + +(doseq [type [clojure.lang.PersistentArrayMap + clojure.lang.PersistentHashMap + clojure.lang.PersistentHashSet + clojure.lang.PersistentVector + clojure.lang.PersistentQueue + clojure.lang.PersistentStructMap + clojure.lang.PersistentTreeMap + clojure.lang.PersistentTreeSet]] + (extend type Walkable {:-walk -walk-default})) + +(defn walk + [inner outer form] + (outer (-walk form inner))) + +(defn postwalk [f form] (walk (partial postwalk f) f form)) + +(defn- keywordize + [m] + (persistent! + (reduce-kv + (fn [m k v] (if (string? k) (assoc! m (keyword k) v) m)) + (transient {}) + m))) + +(defn keywordize-keys + [m] + (postwalk (fn [x] (if (map? x) (keywordize m) x)) m))