(defn
map-spec-impl
"Do not call this directly, use 'spec' with a map argument"
[{:keys
[req-un
opt-un
keys-pred
pred-exprs
opt-keys
req-specs
req
req-keys
opt-specs
pred-forms
opt
gfn],
:as argm}]
(let
[k->s
(zipmap (concat req-keys opt-keys) (concat req-specs opt-specs))
keys->specnames
(fn* [p1__18552#] (c/or (k->s p1__18552#) p1__18552#))
id
(random-uuid)]
(reify
Specize
(specize* [s] s)
(specize* [s _] s)
Spec
(conform*
[_ m]
(if
(keys-pred m)
(let
[reg (registry)]
(loop
[ret m [[k v] & ks :as keys] m]
(if
keys
(let
[sname (keys->specnames k)]
(if-let
[s (get reg sname)]
(let
[cv (conform s v)]
(if
(invalid? cv)
:clojure.core/invalid
(recur (if (identical? cv v) ret (assoc ret k cv)) ks)))
(recur ret ks)))
ret)))
:clojure.core/invalid))
(unform*
[_ m]
(let
[reg (registry)]
(loop
[ret m [k & ks :as keys] (c/keys m)]
(if
keys
(if
(contains? reg (keys->specnames k))
(let
[cv (get m k) v (unform (keys->specnames k) cv)]
(recur (if (identical? cv v) ret (assoc ret k v)) ks))
(recur ret ks))
ret))))
(explain*
[_ path via in x]
(if-not
(map? x)
[{:path path, :pred 'map?, :val x, :via via, :in in}]
(let
[reg (registry)]
(apply
concat
(when-let
[probs
(->>
(map
(fn [pred form] (when-not (pred x) form))
pred-exprs
pred-forms)
(keep identity)
seq)]
(map
(fn*
[p1__18553#]
(identity
{:path path, :pred p1__18553#, :val x, :via via, :in in}))
probs))
(map
(fn
[[k v]]
(when-not
(c/or
(not (contains? reg (keys->specnames k)))
(pvalid? (keys->specnames k) v k))
(explain-1
(keys->specnames k)
(keys->specnames k)
(conj path k)
via
(conj in k)
v)))
(seq x))))))
(gen*
[_ overrides path rmap]
(if
gfn
(gfn)
(let
[rmap
(inck rmap id)
gen
(fn [k s] (gensub s overrides (conj path k) rmap k))
ogen
(fn
[k s]
(when-not
(recur-limit? rmap id path k)
[k (gen/delay (gensub s overrides (conj path k) rmap k))]))
req-gens
(map gen req-keys req-specs)
opt-gens
(remove nil? (map ogen opt-keys opt-specs))]
(when
(every? identity (concat req-gens opt-gens))
(let
[reqs (zipmap req-keys req-gens) opts (into {} opt-gens)]
(gen/bind
(gen/choose 0 (count opts))
(fn*
[p1__18554#]
(let
[args
(concat (seq reqs) (when (seq opts) (shuffle (seq opts))))]
(->>
args
(take (c/+ p1__18554# (count reqs)))
(apply concat)
(apply gen/hash-map))))))))))
(with-gen* [_ gfn] (map-spec-impl (assoc argm :gfn gfn)))
(describe*
[_]
(cons
'clojure.core/keys
(cond->
[]
req
(conj :req req)
opt
(conj :opt opt)
req-un
(conj :req-un req-un)
opt-un
(conj :opt-un opt-un)))))))