Merge pull request #506 from bsless/faster-keywordize

Faster keywordize
This commit is contained in:
Tommi Reiman 2024-08-27 14:11:48 +03:00 committed by GitHub
commit bffe360c6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 64 additions and 1 deletions

View file

@ -1,5 +1,5 @@
(ns reitit.coercion (ns reitit.coercion
(:require [clojure.walk :as walk] (:require [#?(:clj reitit.walk :cljs clojure.walk) :as walk]
[reitit.impl :as impl]) [reitit.impl :as impl])
#?(:clj #?(:clj
(:import (java.io Writer)))) (:import (java.io Writer))))

View file

@ -0,0 +1,50 @@
(ns ^:no-doc reitit.walk)
(defprotocol IKeywordize
(-keywordize [coll]))
(defn keywordize-keys [m] (-keywordize m))
(defn- keywordize-kv
[m k v]
(assoc! m (if (string? k) (keyword k) (-keywordize k)) (-keywordize v)))
(defn- -keywordize-map
[m]
(persistent! (reduce-kv keywordize-kv (transient (empty m)) m)))
(def ^:private keywordize-xf (map keywordize-keys))
(defn- -keywordize-default
[coll]
(into (empty coll) keywordize-xf coll))
(doseq [type [clojure.lang.PersistentHashSet
clojure.lang.PersistentVector
clojure.lang.PersistentQueue
clojure.lang.PersistentStructMap
clojure.lang.PersistentTreeSet]]
(extend type IKeywordize {:-keywordize -keywordize-default}))
(doseq [type [clojure.lang.PersistentArrayMap
clojure.lang.PersistentHashMap
clojure.lang.PersistentTreeMap]]
(extend type IKeywordize {:-keywordize -keywordize-map}))
(extend-protocol IKeywordize
Object
(-keywordize [x] x)
nil
(-keywordize [_] nil)
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)))

View file

@ -0,0 +1,13 @@
(ns reitit.walk-test
(:require
[clojure.test.check.clojure-test :refer [defspec]]
[clojure.test.check.properties :as prop]
[clojure.test.check.generators :as gen]
[clojure.walk :as walk]
[reitit.walk :as sut]))
(defspec keywordize=walk-keywordize
10000
(prop/for-all [v gen/any-equatable]
(= (sut/keywordize-keys v)
(walk/keywordize-keys v))))