boot.user=> (s/def ::my-map (s/and (s/keys :req [::a ::b]) (s/map-of #{::a ::b} any?))) boot.user=> (s/explain ::my-map {::a 1 ::b 2 ::BAD 3}) In: [:boot.user/BAD 0] val: :boot.user/BAD fails spec: :boot.user/my-map at: [0] predicate: #{:boot.user/a :boot.user/b}
Seems better On Tuesday, September 20, 2016 at 5:38:10 AM UTC-7, David Goldfarb wrote: > > In clojure.spec, how can I declare a map that accepts only certain keys? > > *{::a 1 ::b 2 ::BAD 3}* does conform to *(s/keys :req :req [::a ::b])*, > but I want a spec that will be bothered by ::BAD or any other undeclared > key. > > My use case: I am introducing spec to some legacy code, and I want to be > warned if I have failed to specify some elements that may appear in my map. > > > Question 2: > > So, assuming that this is not possible currently, I brute-forced it with: > > *(defn- key-checker [valid-keys]* > * (fn [map-to-check]* > * (empty? (clojure.set/difference (into #{} (keys map-to-check)) > valid-keys))))* > > *(s/def ::my-map (s/and (s/keys :req [::a ::b]) (key-checker #{::a > ::b})))* > > > Ignoring the ugly, and easily fixable, smell of the duplicated set of > keys, this has a bigger problem: > > If the predicate fails, the error that assert gives me is *"{... big ugly > map ...} fails predicate: (key-checker #{::a ::b})"* with no easy way for > the viewer to see which key failed. Can I somehow hook into the explain > mechanism to give a more useful message? > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.