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.

Reply via email to