diff --git a/src/clj/com/rpl/specter.cljx b/src/clj/com/rpl/specter.cljx index c0802bf..a93e01e 100644 --- a/src/clj/com/rpl/specter.cljx +++ b/src/clj/com/rpl/specter.cljx @@ -217,6 +217,21 @@ (set/union newset)) ))) +(defpath + ^{:doc "Navigates to the specified submap (using select-keys). + In a transform, that submap in the original map is changed to the new + value of the submap."} + submap + [m-keys] + (select* [this structure next-fn] + (next-fn (select-keys structure m-keys))) + + (transform* [this structure next-fn] + (let [submap (select-keys structure m-keys) + newmap (next-fn submap)] + (merge (reduce dissoc structure m-keys) + newmap)))) + (defpath walker [afn] diff --git a/test/com/rpl/specter/core_test.cljx b/test/com/rpl/specter/core_test.cljx index d23bd34..8a8130c 100644 --- a/test/com/rpl/specter/core_test.cljx +++ b/test/com/rpl/specter/core_test.cljx @@ -573,6 +573,18 @@ (= (s/setval (s/subset s3) s4 combined) (-> combined (set/difference s2) (set/union s4))) )))) +(deftest submap-test + (is (= [{:foo 1}] + (s/select [(s/submap [:foo :baz])] {:foo 1 :bar 2}))) + (is (= {:foo 1, :barry 1} + (s/setval [(s/submap [:bar])] {:barry 1} {:foo 1 :bar 2}))) + (is (= {:bar 1, :foo 2} + (s/transform [(s/submap [:foo :baz]) s/ALL s/LAST] inc {:foo 1 :bar 1}))) + (is (= {:a {:new 1} + :c {:new 1 + :old 1}} + (s/setval [s/ALL s/LAST (s/submap [])] {:new 1} {:a nil, :c {:old 1}})))) + (deftest nil->val-test (is (= {:a #{:b}} (s/setval [:a s/NIL->SET (s/subset #{})] #{:b} nil)))