Fork me on GitHub
#clojure-spec
<
2018-12-27
>
thomas18:12:37

Hi All, I have been trying to write a spec recently and I can't quite describe what I want... I have a map where two sets of keys depend on each other like this:

thomas18:12:14

{:a "string"
   :b :value-b
   :c :value-c}
or
{:a "string"
  :b :value-not-b
  :c :value-not-c}
and the :b and :c values depend on each other.

manutter5118:12:47

( try three backticks to format that without emojis)

thomas18:12:51

so I either have to first version of the second one.

thomas18:12:41

I assume I need something with an or and an and but how exactly?

manutter5118:12:04

I’m fairly shaky on spec still, but I’m thinking maybe you could take advantage of namespaced vs. unnamespaced keys, let me see if I can type up what I’m thinking

thomas18:12:31

thank you... I don't get it either yet I'm 'fraid

manutter5118:12:04

(s/def :any/a int?)
(s/def :is-value/b #{1 2 3})
(s/def :is-not-value/b #{4 5 6})
(s/def :is-value/c #{1 2 3})
(s/def :is-not-value/c #{4 5 6})
(s/def :is-or-not/my-map
  (s/or :is (s/keys :req-un [:any/a :is-value/b :is-value/c])
        :is-not (s/keys :req-un [:any/a :is-not-value/b :is-not-value/c])))

manutter5118:12:11

I’ve got a suspicion that won’t work, because maps are spec’ed by key, not by value, but a perverse part of my brain is saying maybe it would, because the keys are defined to take two mutually exclusive sets.

thomas18:12:36

let me give that a try @manutter51

thomas18:12:33

I just did a few generates on that and that looks like it does work!

manutter5118:12:07

Generates seem like they’d be more likely to succeed, but I’m not as confident about conforms with “bad” data.

manutter5118:12:26

maybe, though? 🤞

thomas18:12:52

well... I assume if it generates the correct data, then the other way round should work as well.

thomas18:12:04

but let me try...

thomas18:12:52

yes, validating works as well as expected.

thomas18:12:04

Thank you again @manutter51!!!

manutter5118:12:28

That’s pretty wild, I’ll have to remember that one myself.

thomas18:12:43

a good trick to use the namespaces for that... I wouldn't have thought of that.

thomas18:12:58

I suspect it is something that happens more often.

taylor19:12:10

I think you could also combine your s/keys spec using s/and with another predicate, and do any "custom" assertions in the extra predicate