Skip to content

Commit

Permalink
first pass at fix to redplanetlabs#320
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-mor committed Sep 13, 2024
1 parent 67e8680 commit a9ba241
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 92 deletions.
191 changes: 99 additions & 92 deletions src/clj/com/rpl/specter/navs.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -77,69 +77,76 @@
#?(: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
(all-transform [structure next-fn]
(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)
Expand All @@ -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)))))))



Expand Down
5 changes: 5 additions & 0 deletions test/com/rpl/specter/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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"]))
Expand Down

0 comments on commit a9ba241

Please sign in to comment.