diff --git a/src/clj/com/rpl/specter.clj b/src/clj/com/rpl/specter.clj index f457483..dc848e2 100644 --- a/src/clj/com/rpl/specter.clj +++ b/src/clj/com/rpl/specter.clj @@ -102,6 +102,11 @@ (defn keypath [akey] (->KeyPath akey)) +(defn view [afn] (->ViewPath afn)) + +(defmacro viewfn [& args] + `(view (fn ~@args))) + (extend-type clojure.lang.Keyword StructurePath (select* [kw structure next-fn] diff --git a/src/clj/com/rpl/specter/impl.clj b/src/clj/com/rpl/specter/impl.clj index afa49d9..f6c4e6c 100644 --- a/src/clj/com/rpl/specter/impl.clj +++ b/src/clj/com/rpl/specter/impl.clj @@ -232,7 +232,6 @@ (key-update akey structure next-fn) )) - (deftype SelectorValsPath [sel-fn selector] ValPath (select-val [this structure] @@ -257,3 +256,11 @@ (vec res) res )))) + +(deftype ViewPath [view-fn] + StructurePath + (select* [this structure next-fn] + (-> structure view-fn next-fn)) + (update* [this structure next-fn] + (-> structure view-fn next-fn) + )) diff --git a/test/clj/com/rpl/specter/core_test.clj b/test/clj/com/rpl/specter/core_test.clj index a3cc319..4576532 100644 --- a/test/clj/com/rpl/specter/core_test.clj +++ b/test/clj/com/rpl/specter/core_test.clj @@ -210,3 +210,13 @@ (is (= 3 (select-one :b {:a 1 :b 3}))) (is (= 5 (select-one (comp-structure-paths :a :b) {:a {:b 5}}))) ) + +(defspec view-test + (for-all+ + [i gen/int + afn (gen/elements [inc dec])] + (= (first (select (view afn) i)) + (first (select (viewfn [i] (afn i)) i)) + (afn i) + (update (view afn) identity i) + )))