From a9ba241f992d56284b3d8859d3148e285d12438e Mon Sep 17 00:00:00 2001 From: tommy-mor Date: Fri, 13 Sep 2024 11:08:24 -0400 Subject: [PATCH] first pass at fix to #320 --- src/clj/com/rpl/specter/navs.cljc | 191 ++++++++++++++-------------- test/com/rpl/specter/core_test.cljc | 5 + 2 files changed, 104 insertions(+), 92 deletions(-) diff --git a/src/clj/com/rpl/specter/navs.cljc b/src/clj/com/rpl/specter/navs.cljc index a587402..b37ebc7 100644 --- a/src/clj/com/rpl/specter/navs.cljc +++ b/src/clj/com/rpl/specter/navs.cljc @@ -77,31 +77,38 @@ #?(:clj clojure.lang.MapEntry) #?(:clj (all-transform [structure next-fn] - (let [newk (next-fn (key structure)) - newv (next-fn (val structure))] - (clojure.lang.MapEntry. newk newv)))) + (let [newk (next-fn (key structure)) + newv (next-fn (val structure))] + (clojure.lang.MapEntry. newk newv)))) #?(:cljs cljs.core/MapEntry) #?(:cljs (all-transform [structure next-fn] - (let [newk (next-fn (key structure)) - newv (next-fn (val structure))] - (cljs.core/->MapEntry newk newv nil)))) + (let [newk (next-fn (key structure)) + newv (next-fn (val structure))] + (cljs.core/->MapEntry newk newv nil)))) #?(:clj clojure.lang.IPersistentVector :cljs cljs.core/PersistentVector) (all-transform [structure next-fn] (into [] - (comp (map next-fn) - (filter not-NONE?)) - structure)) + (comp (map next-fn) + (filter not-NONE?)) + structure)) + + #?(:clj java.lang.String :cljs string) + (all-transform [structure next-fn] + (apply str (into [] + (comp (map next-fn) + (filter not-NONE?)) + structure))) #?(:clj clojure.lang.PersistentHashSet :cljs cljs.core/PersistentHashSet) (all-transform [structure next-fn] (into #{} - (comp (map next-fn) - (filter not-NONE?)) - structure)) + (comp (map next-fn) + (filter not-NONE?)) + structure)) #?(:clj clojure.lang.PersistentArrayMap) #?(:bb @@ -109,37 +116,37 @@ (non-transient-map-all-transform structure next-fn {})) :clj (all-transform [structure next-fn] - (let [k-it (.keyIterator structure) - v-it (.valIterator structure) - none-cell (i/mutable-cell 0) - len (.count structure) - array (i/fast-object-array (* 2 len))] - (loop [i 0 - j 0] - (if (.hasNext k-it) - (let [k (.next k-it) - v (.next v-it) - newkv (next-fn [k v])] - (if (void-transformed-kv-pair? newkv) - (do - (i/update-cell! none-cell inc) - (recur (+ i 2) j)) - (do - (aset array j (nth newkv 0)) - (aset array (inc j) (nth newkv 1)) - (recur (+ i 2) (+ j 2))))))) - (let [none-count (i/get-cell none-cell) - array (if (not= 0 none-count) - (java.util.Arrays/copyOf array (int (* 2 (- len none-count)))) - array - )] - (clojure.lang.PersistentArrayMap/createAsIfByAssoc array))))) + (let [k-it (.keyIterator structure) + v-it (.valIterator structure) + none-cell (i/mutable-cell 0) + len (.count structure) + array (i/fast-object-array (* 2 len))] + (loop [i 0 + j 0] + (if (.hasNext k-it) + (let [k (.next k-it) + v (.next v-it) + newkv (next-fn [k v])] + (if (void-transformed-kv-pair? newkv) + (do + (i/update-cell! none-cell inc) + (recur (+ i 2) j)) + (do + (aset array j (nth newkv 0)) + (aset array (inc j) (nth newkv 1)) + (recur (+ i 2) (+ j 2))))))) + (let [none-count (i/get-cell none-cell) + array (if (not= 0 none-count) + (java.util.Arrays/copyOf array (int (* 2 (- len none-count)))) + array + )] + (clojure.lang.PersistentArrayMap/createAsIfByAssoc array))))) #?(:cljs cljs.core/PersistentArrayMap) #?(:cljs (all-transform [structure next-fn] - (non-transient-map-all-transform structure next-fn {}))) + (non-transient-map-all-transform structure next-fn {}))) #?(:clj clojure.lang.PersistentTreeMap :cljs cljs.core/PersistentTreeMap) @@ -148,81 +155,81 @@ #?(:clj clojure.lang.IRecord) #?(:clj - (all-transform [structure next-fn] - (all-transform-record structure next-fn))) + (all-transform [structure next-fn] + (all-transform-record structure next-fn))) #?(:clj clojure.lang.PersistentHashMap :cljs cljs.core/PersistentHashMap) (all-transform [structure next-fn] (persistent! - (reduce-kv - (fn [m k v] - (let [newkv (next-fn [k v])] - (if (void-transformed-kv-pair? newkv) - m - (assoc! m (nth newkv 0) (nth newkv 1))))) + (reduce-kv + (fn [m k v] + (let [newkv (next-fn [k v])] + (if (void-transformed-kv-pair? newkv) + m + (assoc! m (nth newkv 0) (nth newkv 1))))) - (transient - #?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY)) + (transient + #?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY)) - structure))) + structure))) #?(:clj Object) #?(:clj (all-transform [structure next-fn] - (let [empty-structure (empty structure)] - (cond (and (list? empty-structure) (not (queue? empty-structure))) - (all-transform-list structure next-fn) + (let [empty-structure (empty structure)] + (cond (and (list? empty-structure) (not (queue? empty-structure))) + (all-transform-list structure next-fn) - (map? structure) - ;; reduce-kv is much faster than doing r/map through call to (into ...) - (reduce-kv - (fn [m k v] - (let [newkv (next-fn [k v])] - (if (void-transformed-kv-pair? newkv) - m - (assoc m (nth newkv 0) (nth newkv 1))))) + (map? structure) + ;; reduce-kv is much faster than doing r/map through call to (into ...) + (reduce-kv + (fn [m k v] + (let [newkv (next-fn [k v])] + (if (void-transformed-kv-pair? newkv) + m + (assoc m (nth newkv 0) (nth newkv 1))))) - empty-structure - structure) + empty-structure + structure) - :else - #?(:bb (into empty-structure - (comp (map next-fn) (filter not-NONE?)) - structure) - :clj (->> structure - (r/map next-fn) - (r/filter not-NONE?) - (into empty-structure))))))) + :else + #?(:bb (into empty-structure + (comp (map next-fn) (filter not-NONE?)) + structure) + :clj (->> structure + (r/map next-fn) + (r/filter not-NONE?) + (into empty-structure))))))) #?(:cljs default) #?(:cljs (all-transform [structure next-fn] - (if (record? structure) - ;; this case is solely for cljs since extending to IRecord doesn't work for cljs - (all-transform-record structure next-fn) - (let [empty-structure (empty structure)] - (cond - (and (list? empty-structure) (not (queue? empty-structure))) - (all-transform-list structure next-fn) - - (map? structure) - (reduce-kv - (fn [m k v] - (let [newkv (next-fn [k v])] - (if (void-transformed-kv-pair? newkv) - m - (assoc m (nth newkv 0) (nth newkv 1))))) - empty-structure - structure) - - :else - (into empty-structure - (comp (map next-fn) (filter not-NONE?)) - structure))))))) + (if (record? structure) + ;; this case is solely for cljs since extending to IRecord doesn't work for cljs + (all-transform-record structure next-fn) + (let [empty-structure (empty structure)] + (cond + (and (list? empty-structure) (not (queue? empty-structure))) + (all-transform-list structure next-fn) + + (map? structure) + (reduce-kv + (fn [m k v] + (let [newkv (next-fn [k v])] + (if (void-transformed-kv-pair? newkv) + m + (assoc m (nth newkv 0) (nth newkv 1))))) + empty-structure + structure) + + :else + (into empty-structure + (comp (map next-fn) (filter not-NONE?)) + structure))))))) diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 1ba123c..e8b416c 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -1440,6 +1440,11 @@ (is (= "abq" (setval s/LAST "q" "abc"))) ) +(deftest string-transform-test + (is (= "123" (transform s/ALL identity "123"))) + (is (= "123" (setval [s/ALL #(Character/isWhitespace %)] s/NONE "1 2 3"))) + (is (= "123" (transform [(s/filterer #(Character/isWhitespace %))] s/NONE "1 2 3")))) + (deftest regex-navigation-test ;; also test regexes as implicit navs (is (= (select #"t" "test") ["t" "t"]))