Skip to content

Commit

Permalink
Support MAP-VALS for records
Browse files Browse the repository at this point in the history
Add implementation for IRecord almost identical to that of Object, but using a new empty-record fn

Throwing exception from map-keys-transform, since it doesn't really make sense to change the keys of a record

Adding simple test
  • Loading branch information
jeff303 committed Apr 22, 2021
1 parent e8225f0 commit 6bf7e93
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/clj/com/rpl/specter/navs.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,19 @@
empty-map
structure))

;; adapted from https://stackoverflow.com/a/45447810/375670
(defn- empty-record
"Creates a new instance of the given record, with all values nil"
[record]
(reduce
(fn [record k]
(let [without (dissoc record k)]
(if (= (type record) (type without))
without
(assoc record k nil))))
record
(keys record)))

(extend-protocol MapTransformProtocol
nil
(map-vals-transform [structure next-fn]
Expand Down Expand Up @@ -370,7 +383,21 @@
m
(assoc m newk v))))
(empty structure)
structure)))
structure))

#?(:clj clojure.lang.IRecord :cljs cljs.core/IRecord)
(map-vals-transform [structure next-fn]
(reduce-kv
(fn [m k v]
(let [newv (next-fn v)]
(if (identical? newv i/NONE)
m
(assoc m k newv))))
(empty-record structure)
structure))
(map-keys-transform [structure _]
(throw (ex-info "Can't transform keys of a record"
{:record structure}))))

(defn srange-select [structure start end next-fn]
(next-fn
Expand Down
10 changes: 10 additions & 0 deletions test/com/rpl/specter/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,16 @@
(multi-transform (s/terminal (f #?(:clj String :cljs js/String))) 1)))
))

(defrecord TestRecord [a b c])

(deftest map-navs-on-records-test
(let [r (TestRecord. 8 -12 91)]
(is (= {:a 9 :b -11 :c 92} (into {} (transform [s/MAP-VALS] inc r))))
(is (thrown-with-msg?
Exception
#"Can't transform keys of a record"
(transform [s/MAP-KEYS] #(case % :a :x :b :y :c :z) r)))))

#?(:clj
(do
(defprotocolpath FooPP)
Expand Down

0 comments on commit 6bf7e93

Please sign in to comment.