(defn
spec-impl
"Do not call this directly, use 'spec'"
([form pred gfn cpred?] (spec-impl form pred gfn cpred? nil))
([form pred gfn cpred? unc]
(cond
(spec? pred)
(cond-> pred gfn (with-gen gfn))
(regex? pred)
(regex-spec-impl pred gfn)
(ident? pred)
(cond-> (the-spec pred) gfn (with-gen gfn))
:else
(reify
Specize
(specize* [s] s)
(specize* [s _] s)
Spec
(conform*
[_ x]
(let
[ret (pred x)]
(if cpred? ret (if ret x :clojure.core/invalid))))
(unform*
[_ x]
(if
cpred?
(if unc (unc x) (throw (js/Error. "no unform fn for conformer")))
x))
(explain*
[_ path via in x]
(when
(invalid? (dt pred x form cpred?))
[{:path path, :pred form, :val x, :via via, :in in}]))
(gen* [_ _ _ _] (if gfn (gfn) (gen/gen-for-pred pred)))
(with-gen* [_ gfn] (spec-impl form pred gfn cpred? unc))
(describe* [_] form)))))