Closed jeaye closed 7 years ago
Hi. You need to wrap s/keys
into Spec Records (via st/spec
) as clojure.spec doesn't support selective runtime conforming out-of-the-box. See https://dev.clojure.org/jira/browse/CLJ-2116 & the README example https://github.com/metosin/spec-tools#map-conforming.
Good thing is that creating the spec record makes this really fast as it captures all the possible keys at creation time and the actual select-spec
just runs on select-keys
per spec.
I'll add a FAQ into the README for this.
Ah, indeed, it was something simple I missed. Thanks for the info and for the FAQ entry!
Looks like it won't work with any merging though, is that right?
Do you have an example of merging where it doesn't work?
Oh, you know what, it's because I have a multi-spec merged in.
(require '[clojure.spec.alpha :as s])
(require '[spec-tools.core :as st])
(s/def ::a int?)
(s/def ::b string?)
(s/def ::c keyword?)
(s/def ::map1 (st/spec (s/keys :req-un [::a])))
(s/def ::map2 (st/spec (s/keys :req-un [::b])))
(s/def ::map3 (st/spec (s/keys :req-un [::c])))
(defmulti myspec :type)
(defmethod myspec 3 [_] ::map2 )
(s/def ::map3 (s/merge ::map1 ::map2 (st/spec (s/multi-spec myspec :type))))
(def test-map-3 {:a 1 :b "hi" :type 3 :c :keep-me :d :remove-me})
(s/valid? ::map3 test-map-3)
;;=> true
(st/select-spec ::map3 test-map-3)
;;=>{:a 1, :b "hi", :type 3, :c :keep-me, :d :remove-me}
Hey there.
select-spec
looked like the perfect tool for the job when I was hoping to take a map of X + N keys and pull out only X. Alas, it doesn't seem to be doing anything for me. Perhaps it's a bug, but more likely I'm missing something simple.