I've enjoyed working with clojure.spec
; it has helped uncover data errors closer to the cause. Currently I am using it to validate a response to a web server request, but I am having difficulty with the syntax for the clojure.spec operation that would allow two different map structure responses.
In my data, there are two possible responses from the web server request:
{:assignment "1232123"}
and
{:no-more-assignments true}
I could use multi-spec
, but that seems verbose for something that could be as simple as having one spec for each case and defining the spec as:
(s/def ::response
(s/or ::case-1 ::case-2))
Is there some syntax that I am overlooking or will I need to use multi-spec
?
You can use or
and and
with keys
specs:
(s/def ::assignment string?)
(s/def ::no-more-assignments boolean?)
(s/def ::response
(s/keys :req-un [(or ::assignment ::no-more-assignments)]))
(s/explain ::response {:assignment "123"})
;; Success!
(s/explain ::response {:foo true})
;; val: {:foo true} fails spec: :sandbox.so/response predicate: (or (contains? % :assignment) (contains? % :no-more-assignments))