(defn
or-spec-impl
"Do not call this directly, use 'or'"
[keys forms preds gfn]
(let
[id
(random-uuid)
kps
(zipmap keys preds)
specs
(delay (mapv specize preds forms))
cform
(case
(count preds)
2
(fn
[x]
(let
[specs @specs ret (conform* (specs 0) x)]
(if
(invalid? ret)
(let
[ret (conform* (specs 1) x)]
(if
(invalid? ret)
:clojure.core/invalid
(tagged-ret [(keys 1) ret])))
(tagged-ret [(keys 0) ret]))))
3
(fn
[x]
(let
[specs @specs ret (conform* (specs 0) x)]
(if
(invalid? ret)
(let
[ret (conform* (specs 1) x)]
(if
(invalid? ret)
(let
[ret (conform* (specs 2) x)]
(if
(invalid? ret)
:clojure.core/invalid
(tagged-ret [(keys 2) ret])))
(tagged-ret [(keys 1) ret])))
(tagged-ret [(keys 0) ret]))))
(fn
[x]
(let
[specs @specs]
(loop
[i 0]
(if
(< i (count specs))
(let
[spec (specs i)]
(let
[ret (conform* spec x)]
(if
(invalid? ret)
(recur (inc i))
(tagged-ret [(keys i) ret]))))
:clojure.core/invalid)))))]
(reify
Specize
(specize* [s] s)
(specize* [s _] s)
Spec
(conform* [_ x] (cform x))
(unform* [_ [k x]] (unform (kps k) x))
(explain*
[this path via in x]
(when-not
(pvalid? this x)
(apply
concat
(map
(fn
[k form pred]
(when-not
(pvalid? pred x)
(explain-1 form pred (conj path k) via in x)))
keys
forms
preds))))
(gen*
[_ overrides path rmap]
(if
gfn
(gfn)
(let
[gen
(fn
[k p f]
(let
[rmap (inck rmap id)]
(when-not
(recur-limit? rmap id path k)
(gen/delay (gensub p overrides (conj path k) rmap f)))))
gs
(remove nil? (map gen keys preds forms))]
(when-not (empty? gs) (gen/one-of gs)))))
(with-gen* [_ gfn] (or-spec-impl keys forms preds gfn))
(describe*
[_]
(clojure.core/sequence
(clojure.core/seq
(clojure.core/concat
(clojure.core/list 'clojure.core/or)
(mapcat vector keys forms))))))))