Support MAP-VALS for records

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
This commit is contained in:
Jeff Evans 2021-04-22 09:50:05 -05:00
parent e8225f0e58
commit 6bf7e932d0
2 changed files with 38 additions and 1 deletions

View file

@ -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]
@ -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

View file

@ -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)