mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 08:51:12 +00:00
Tailor keywordize implementation to concrete types
Even faster
This commit is contained in:
parent
7ab6021630
commit
dcb7258caf
1 changed files with 38 additions and 39 deletions
|
|
@ -1,52 +1,51 @@
|
||||||
(ns ^:no-doc reitit.walk)
|
(ns ^:no-doc reitit.walk)
|
||||||
|
|
||||||
(defprotocol Walkable
|
(defprotocol IKeywordize
|
||||||
(-walk [coll f]))
|
(-keywordize [coll]))
|
||||||
|
|
||||||
(extend-protocol Walkable
|
(defn- -keywordize-map
|
||||||
nil
|
[m]
|
||||||
(-walk [_ _] nil)
|
(persistent!
|
||||||
Object
|
(reduce-kv
|
||||||
(-walk [x _] x)
|
(fn [m k v]
|
||||||
clojure.lang.IMapEntry
|
(if (string? k)
|
||||||
(-walk [e f] (clojure.lang.MapEntry. (f (.key e)) (f (.val e))))
|
(assoc! m (keyword k) (-keywordize v))
|
||||||
clojure.lang.ISeq
|
(assoc! m (-keywordize k) (-keywordize v))))
|
||||||
(-walk [coll f] (map f coll))
|
(transient (empty m))
|
||||||
clojure.lang.PersistentList
|
m)))
|
||||||
(-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
|
(defn- -keywordize-default
|
||||||
[coll f]
|
[coll]
|
||||||
(into (empty coll) (map f) coll))
|
(into (empty coll) (map -keywordize) coll))
|
||||||
|
|
||||||
(doseq [type [clojure.lang.PersistentArrayMap
|
(doseq [type [clojure.lang.PersistentHashSet
|
||||||
clojure.lang.PersistentHashMap
|
|
||||||
clojure.lang.PersistentHashSet
|
|
||||||
clojure.lang.PersistentVector
|
clojure.lang.PersistentVector
|
||||||
clojure.lang.PersistentQueue
|
clojure.lang.PersistentQueue
|
||||||
clojure.lang.PersistentStructMap
|
clojure.lang.PersistentStructMap
|
||||||
clojure.lang.PersistentTreeMap
|
clojure.lang.PersistentTreeMap
|
||||||
clojure.lang.PersistentTreeSet]]
|
clojure.lang.PersistentTreeSet]]
|
||||||
(extend type Walkable {:-walk -walk-default}))
|
(extend type IKeywordize {:-keywordize -keywordize-default}))
|
||||||
|
|
||||||
(defn walk
|
(doseq [type [clojure.lang.PersistentArrayMap
|
||||||
[inner outer form]
|
clojure.lang.PersistentHashMap]]
|
||||||
(outer (-walk form inner)))
|
(extend type IKeywordize {:-keywordize -keywordize-map}))
|
||||||
|
|
||||||
(defn postwalk [f form] (walk (partial postwalk f) f form))
|
(extend-protocol IKeywordize
|
||||||
|
nil
|
||||||
|
(-keywordize [_] nil)
|
||||||
|
Object
|
||||||
|
(-keywordize [x] x)
|
||||||
|
clojure.lang.MapEntry
|
||||||
|
(-keywordize [e] (clojure.lang.MapEntry/create
|
||||||
|
(-keywordize (.key e))
|
||||||
|
(-keywordize (.val e))))
|
||||||
|
clojure.lang.ISeq
|
||||||
|
(-keywordize [coll] (map -keywordize coll))
|
||||||
|
clojure.lang.PersistentList
|
||||||
|
(-keywordize [coll] (apply list (map -keywordize coll)))
|
||||||
|
clojure.lang.PersistentList$EmptyList
|
||||||
|
(-keywordize [x] x)
|
||||||
|
clojure.lang.IRecord
|
||||||
|
(-keywordize [r] (reduce (fn [r x] (conj r (-keywordize x))) r r)))
|
||||||
|
|
||||||
(defn- keywordize
|
(defn keywordize-keys [m] (-keywordize m))
|
||||||
[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))
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue