diff --git a/scripts/benchmarks.clj b/scripts/benchmarks.clj index 4396209..f82bcd5 100644 --- a/scripts/benchmarks.clj +++ b/scripts/benchmarks.clj @@ -206,3 +206,16 @@ 300000 (transform (submap [600 700]) modify-submap data) (transform (submap! [600 700]) modify-submap tdata))) + +(let [data {:x 1} + meta-map {:my :metadata}] + (run-benchmark "set metadata" + 300000 + (with-meta data meta-map) + (setval META meta-map data))) + +(let [data (with-meta {:x 1} {:my :metadata})] + (run-benchmark "get metadata" + 300000 + (vector (meta data)) + (select META data))) diff --git a/src/clj/com/rpl/specter.cljx b/src/clj/com/rpl/specter.cljx index d55b8e9..6a3871c 100644 --- a/src/clj/com/rpl/specter.cljx +++ b/src/clj/com/rpl/specter.cljx @@ -498,6 +498,15 @@ NIL->VECTOR (nil->val [])) +(defnav ^{:doc "Navigates to the metadata of the structure, or nil if + the structure has no metadata or may not contain metadata."} + META + [] + (select* [this structure next-fn] + (next-fn (meta structure))) + (transform* [this structure next-fn] + (with-meta structure (next-fn (meta structure))))) + (defpathedfn ^{:doc "Adds the result of running select with the given path on the current value to the collected vals."} diff --git a/test/com/rpl/specter/core_test.cljx b/test/com/rpl/specter/core_test.cljx index 9aa1510..febde4e 100644 --- a/test/com/rpl/specter/core_test.cljx +++ b/test/com/rpl/specter/core_test.cljx @@ -1070,3 +1070,12 @@ (persistent! (s/transform* transient-path f (transient m)))) (= (s/select* path m) (s/select* transient-path (transient m))))))))) + +(defspec meta-test + (for-all+ + [v (gen/vector gen/int) + meta-map (limit-size 5 (gen/map gen/keyword gen/int))] + (= meta-map + (meta (setval s/META meta-map v)) + (first (select s/META (with-meta v meta-map))) + (first (select s/META (setval s/META meta-map v))))))