From 2dd6432c6969b7ffe1c4a87d3d2a00e2f1025411 Mon Sep 17 00:00:00 2001 From: nathanmarz Date: Sun, 7 May 2017 19:36:50 -0400 Subject: [PATCH] add set-elem navigator and change semantics of map-key to only navigate if the key exists (for consistency with set-elem) --- CHANGES.md | 1 + src/clj/com/rpl/specter.cljc | 34 +++++++++++++++++++++++------ test/com/rpl/specter/core_test.cljc | 8 ++++++- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3b702b1..dcc6306 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ * Added `pred=`, `pred<`, `pred>`, `pred<=`, `pred>=` for filtering using common comparisons * Add `map-key` navigator +* Add `set-elem` navigator ## 1.0.1 diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc index eb4d71e..499adc3 100644 --- a/src/clj/com/rpl/specter.cljc +++ b/src/clj/com/rpl/specter.cljc @@ -869,17 +869,37 @@ structure))))) (defrichnav - ^{:doc "Navigates to the given key in the map (not to the value). Navigates regardless - of whether the key currently exists in the map. For transforms, will assoc nil - value if key doesn't currently exist in map."} + ^{:doc "Navigates to the given key in the map (not to the value). Navigates only if the + key currently exists in the map."} map-key [key] (select* [this vals structure next-fn] - (next-fn vals key)) + (if (contains? structure key) + (next-fn vals key) + NONE + )) (transform* [this vals structure next-fn] - (let [newkey (next-fn vals key) - oldval (get structure key)] - (-> structure (dissoc key) (assoc newkey oldval)) + (if (contains? structure key) + (let [newkey (next-fn vals key) + oldval (get structure key)] + (-> structure (dissoc key) (assoc newkey oldval)) + ) + structure + ))) + +(defrichnav + ^{:doc "Navigates to the given element in the set only if it exists in the set."} + set-elem + [elem] + (select* [this vals structure next-fn] + (if (contains? structure elem) + (next-fn vals elem) + NONE + )) + (transform* [this vals structure next-fn] + (if (contains? structure elem) + (-> structure (disj elem) (conj (next-fn vals elem))) + structure ))) (def ^{:doc "Navigate to the specified keys one after another. If navigate to NONE, diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 1f9f682..dcd9318 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -1528,11 +1528,17 @@ )) (deftest map-key-test - (is (= {:b nil :c 3} (setval (s/map-key :a) :b {:c 3}))) + (is (= {:c 3} (setval (s/map-key :a) :b {:c 3}))) (is (= {:b 2} (setval (s/map-key :a) :b {:a 2}))) (is (= {:b 2} (setval (s/map-key :a) :b {:a 2 :b 1}))) ) +(deftest set-elem-test + (is (= #{:b :d} (setval (s/set-elem :a) :x #{:b :d}))) + (is (= #{:x :a} (setval (s/set-elem :b) :x #{:b :a}))) + (is (= #{:a} (setval (s/set-elem :b) :a #{:b :a}))) + ) + #?(:clj (do (defprotocolpath FooPP)