From 7ab60216304a347016d292ea6fa672a20c7a8420 Mon Sep 17 00:00:00 2001 From: Ben Sless Date: Mon, 30 Aug 2021 10:10:32 +0300 Subject: [PATCH] Add faster keywordize-keys implementation for clj --- modules/reitit-core/src/reitit/coercion.cljc | 2 +- modules/reitit-core/src/reitit/walk.clj | 52 ++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 modules/reitit-core/src/reitit/walk.clj 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))