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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.