clojure.spec/and & clojure.spec/or

clojure.spec/and & clojure.spec/or can be used to create more complex specs, using multiple specs or predicates:

(clojure.spec/def ::pos-odd (clojure.spec/and odd? pos?))

(clojure.spec/valid? ::pos-odd 1)
;;=> true

(clojure.spec/valid? ::pos-odd -3)
;;=> false

or works similarly, with one significant difference. When defining an or spec, you must tag each possible branch with a keyword. This is used in order to provide specific branches which fail in error messages:

(clojure.spec/def ::big-or-small (clojure.spec/or :small #(< % 10) :big #(> % 100)))

(clojure.spec/valid? ::big-or-small 1)
;;=> true

(clojure.spec/valid? ::big-or-small 150)
;;=> true

(clojure.spec/valid? ::big-or-small 20)
;;=> false

When conforming a spec using or, the applicable spec will be returned which made the value conform:

(clojure.spec/conform ::big-or-small 5)
;; => [:small 5]

if you want to reproduce, please indicate the source:
clojure.spec/and & clojure.spec/or - CodeDay