Fork me on GitHub
#clojure-spec
<
2020-12-10
>
konrad szydlo12:12:40

Hi, I'm trying to figure out how to implement xor for a map keys. Where I'd like to check if one of the keys is present but not both at the same time.

(s/def ::a int?)
(s/def ::b int?)
(s/def ::c string?)
Where following maps are invalid: {::c "string"} ;; missing ::a xor ::b {::a 1 ::b 2 ::c "string"} ;; both ::a and ::b present and the following maps are valid: {::a 1 ::c "string"} {::b 2 ::c "string"}

english14:12:03

s/keys only supports regular or: https://stackoverflow.com/a/41901585 but you could combine the s/keys spec with a custom xor spec via s/and, as described in https://stackoverflow.com/a/43374087

konrad szydlo14:12:55

Thank you. My searching on duck duck go didn't return this answer from SO. That's what I was looking for. In the docs for s/keys I saw that or is supported but not xor

vlaaad14:12:01

(s/and (s/keys ...) #(= 2 (count (select-keys % [::a ::b ::c]))))?