Skip to content

Commit

Permalink
BEFORE-ELEM, AFTER-ELEM, FIRST, LAST, BEGINNING, and END on subvecs n…
Browse files Browse the repository at this point in the history
…ow produce vector type in cljs
  • Loading branch information
nathanmarz committed Sep 17, 2020
1 parent efaf355 commit a379893
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* Add arglist metadata to navs (thanks @phronmophobic)
* Improve before-index performance by 150x on lists and 5x on vectors (thanks @jeff303)
* Bug fix: BEFORE-ELEM, AFTER-ELEM, FIRST, LAST, BEGINNING, and END on subvecs now produce vector type in cljs

## 1.1.3 - 2019-10-13

Expand Down
93 changes: 62 additions & 31 deletions src/clj/com/rpl/specter/navs.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,24 @@
(prepend-one [structure elem]
(into [elem] structure))

#?(:cljs cljs.core/Subvec)
#?(:cljs
(append-all [structure elements]
(reduce conj structure elements)))
#?(:cljs
(prepend-all [structure elements]
(let [ret (transient [])]
(as-> ret <>
(reduce conj! <> elements)
(reduce conj! <> structure)
(persistent! <>)))))
#?(:cljs
(append-one [structure elem]
(conj structure elem)))
#?(:cljs
(prepend-one [structure elem]
(into [elem] structure)))


#?(:clj Object :cljs default)
(append-all [structure elements]
Expand Down Expand Up @@ -487,6 +505,14 @@
structure
(updater structure next-fn))))

#?(
:clj
(defn vec-count [^clojure.lang.IPersistentVector v]
(.length v))

:cljs
(defn vec-count [v]
(count v)))

(defn- update-first-list [l afn]
(let [newf (afn (first l))
Expand All @@ -502,14 +528,33 @@
(if (nil? bl) '() bl)
(concat bl [lastl]))))

#?(
:clj
(defn vec-count [^clojure.lang.IPersistentVector v]
(.length v))
(defn- update-first-vector [v afn]
(let [val (nth v 0)
newv (afn val)]
(if (identical? i/NONE newv)
(subvec v 1)
(assoc v 0 newv)
)))

:cljs
(defn vec-count [v]
(count v)))
(defn- update-last-vector [v afn]
;; type-hinting vec-count to ^int caused weird errors with case
(let [c (int (vec-count v))]
(case c
1 (let [[e] v
newe (afn e)]
(if (identical? i/NONE newe)
[]
[newe]))
2 (let [[e1 e2] v
newe (afn e2)]
(if (identical? i/NONE newe)
[e1]
[e1 newe]))
(let [i (dec c)
newe (afn (nth v i))]
(if (identical? i/NONE newe)
(pop v)
(assoc v i newe))))))


#?(
Expand All @@ -525,32 +570,18 @@
(extend-protocol UpdateExtremes
#?(:clj clojure.lang.IPersistentVector :cljs cljs.core/PersistentVector)
(update-first [v afn]
(let [val (nth v 0)
newv (afn val)]
(if (identical? i/NONE newv)
(subvec v 1)
(assoc v 0 newv)
)))
(update-first-vector v afn))

(update-last [v afn]
;; type-hinting vec-count to ^int caused weird errors with case
(let [c (int (vec-count v))]
(case c
1 (let [[e] v
newe (afn e)]
(if (identical? i/NONE newe)
[]
[newe]))
2 (let [[e1 e2] v
newe (afn e2)]
(if (identical? i/NONE newe)
[e1]
[e1 newe]))
(let [i (dec c)
newe (afn (nth v i))]
(if (identical? i/NONE newe)
(pop v)
(assoc v i newe))))))
(update-last-vector v afn))

#?(:cljs cljs.core/Subvec)
#?(:cljs
(update-first [v afn]
(update-first-vector v afn)))
#?(:cljs
(update-last [v afn]
(update-last-vector v afn)))

#?(:clj String :cljs string)
(update-first [s afn]
Expand Down

0 comments on commit a379893

Please sign in to comment.