Fork me on GitHub
#clojure-spec
<
2017-02-25
>
thedavidmeister02:02:16

is there a way in spec to define relationships between attributes, like #(> ::foo :bar) for example?

joshjones04:02:46

@thedavidmeister

(s/def ::foo int?)
(s/def ::bar int?)
(s/def ::keyspec (s/and (s/keys :req [::foo ::bar])
                        #(> (::foo %) (::bar %))))

thedavidmeister04:02:13

@joshjones so... is % in that context going to be the thing being validated?

joshjones04:02:28

yes -- for example (s/valid? ::keyspec {::foo 2 ::bar 3}) the map is the argument to the function

thedavidmeister04:02:51

so then my next q is

thedavidmeister04:02:19

if i have :req, how do i get a list of the keys that are missing?

joshjones04:02:35

this is not meant to be a 'best practices', just to show how you can get the data:

(->> (s/explain-data ::keyspec {::foo 2})
     :clojure.spec/problems
     (map :pred)
     (filter #(= 'contains? (first %)))
     (map last))

thedavidmeister04:02:34

looks a bit weird but i guess it does the job

thedavidmeister04:02:39

cheers 🙂

Alex Miller (Clojure team)05:02:15

Call explain-data to get a list of all problems

joshjones05:02:38

@thedavidmeister hmm, "weird" is about all I got late Friday after evening activities 🙂 but here you go, same as above but rewritten in a function. cheers to you too

(defn keys-missing
  [spec data]
  (let [explanation (s/explain-data spec data)
        problems (:clojure.spec/problems explanation)
        xf (comp (map :pred)
                 (filter #(= 'contains? (first %)))
                 (map last))]
    (into [] xf problems)))

joshjones05:02:41

it relies on things you possibly shouldn't rely on, like contains? implying that a key is missing, works for now but it's not "public" ... but it's enough to get you going I think 😉

thedavidmeister07:02:16

@joshjones yup, looks good enough for me to start swapping out my hand-rolled validation code

bbloom18:02:01

i forget - was there a collection of attempted/in-progress specs for all the core functions somewhere?

Alex Miller (Clojure team)19:02:00

from core, no (beyond the one ticket out there that slightly extends what’s committed)

Alex Miller (Clojure team)19:02:38

there is another project someone started, but I’ve intentionally not looked at it