|
200 | 200 | (defn explain-data* [spec path via in x] |
201 | 201 | (when-let [probs (explain* (specize spec) path via in x)] |
202 | 202 | (when-not (empty? probs) |
203 | | - {::problems probs}))) |
| 203 | + {::problems probs |
| 204 | + ::spec spec |
| 205 | + ::value x}))) |
204 | 206 |
|
205 | 207 | (defn explain-data |
206 | 208 | "Given a spec and a value x which ought to conform, returns nil if x |
|
215 | 217 | "Default printer for explain-data. nil indicates a successful validation." |
216 | 218 | [ed] |
217 | 219 | (if ed |
218 | | - (print |
219 | | - (with-out-str |
220 | | - ;;(prn {:ed ed}) |
221 | | - (doseq [{:keys [path pred val reason via in] :as prob} (::problems ed)] |
222 | | - (when-not (empty? in) |
223 | | - (print "In:" (pr-str in) "")) |
224 | | - (print "val: ") |
225 | | - (pr val) |
226 | | - (print " fails") |
227 | | - (when-not (empty? via) |
228 | | - (print " spec:" (pr-str (last via)))) |
229 | | - (when-not (empty? path) |
230 | | - (print " at:" (pr-str path))) |
231 | | - (print " predicate: ") |
232 | | - (pr (abbrev pred)) |
233 | | - (when reason (print ", " reason)) |
234 | | - (doseq [[k v] prob] |
235 | | - (when-not (#{:path :pred :val :reason :via :in} k) |
236 | | - (print "\n\t" (pr-str k) " ") |
237 | | - (pr v))) |
238 | | - (newline)) |
239 | | - (doseq [[k v] ed] |
240 | | - (when-not (#{::problems} k) |
241 | | - (print (pr-str k) " ") |
242 | | - (pr v) |
243 | | - (newline))))) |
| 220 | + (let [problems (sort-by #(- (count (:path %))) (::problems ed))] |
| 221 | + (print |
| 222 | + (with-out-str |
| 223 | + ;;(prn {:ed ed}) |
| 224 | + (doseq [{:keys [path pred val reason via in] :as prob} problems] |
| 225 | + (when-not (empty? in) |
| 226 | + (print "In:" (pr-str in) "")) |
| 227 | + (print "val: ") |
| 228 | + (pr val) |
| 229 | + (print " fails") |
| 230 | + (when-not (empty? via) |
| 231 | + (print " spec:" (pr-str (last via)))) |
| 232 | + (when-not (empty? path) |
| 233 | + (print " at:" (pr-str path))) |
| 234 | + (print " predicate: ") |
| 235 | + (pr (abbrev pred)) |
| 236 | + (when reason (print ", " reason)) |
| 237 | + (doseq [[k v] prob] |
| 238 | + (when-not (#{:path :pred :val :reason :via :in} k) |
| 239 | + (print "\n\t" (pr-str k) " ") |
| 240 | + (pr v))) |
| 241 | + (newline)) |
| 242 | + (doseq [[k v] ed] |
| 243 | + (when-not (#{::problems} k) |
| 244 | + (print (pr-str k) " ") |
| 245 | + (pr v) |
| 246 | + (newline)))))) |
244 | 247 | (println "Success!"))) |
245 | 248 |
|
246 | 249 | (def ^:dynamic *explain-out* explain-printer) |
|
371 | 374 | (let [pred (maybe-spec pred)] |
372 | 375 | (if (spec? pred) |
373 | 376 | (explain* pred path (if-let [name (spec-name pred)] (conj via name) via) in v) |
374 | | - [{:path path :pred (abbrev form) :val v :via via :in in}]))) |
| 377 | + [{:path path :pred form :val v :via via :in in}]))) |
375 | 378 |
|
376 | 379 | (defn ^:skip-wiki map-spec-impl |
377 | 380 | "Do not call this directly, use 'spec' with a map argument" |
|
417 | 420 | [{:path path :pred 'map? :val x :via via :in in}] |
418 | 421 | (let [reg (registry)] |
419 | 422 | (apply concat |
420 | | - (when-let [probs (->> (map (fn [pred form] (when-not (pred x) (abbrev form))) |
| 423 | + (when-let [probs (->> (map (fn [pred form] (when-not (pred x) form)) |
421 | 424 | pred-exprs pred-forms) |
422 | 425 | (keep identity) |
423 | 426 | seq)] |
|
482 | 485 | x)) |
483 | 486 | (explain* [_ path via in x] |
484 | 487 | (when (invalid? (dt pred x form cpred?)) |
485 | | - [{:path path :pred (abbrev form) :val x :via via :in in}])) |
| 488 | + [{:path path :pred form :val x :via via :in in}])) |
486 | 489 | (gen* [_ _ _ _] (if gfn |
487 | 490 | (gfn) |
488 | 491 | (gen/gen-for-pred pred))) |
|
518 | 521 | path (conj path dv)] |
519 | 522 | (if-let [pred (predx x)] |
520 | 523 | (explain-1 form pred path via in x) |
521 | | - [{:path path :pred (abbrev form) :val x :reason "no method" :via via :in in}]))) |
| 524 | + [{:path path :pred form :val x :reason "no method" :via via :in in}]))) |
522 | 525 | (gen* [_ overrides path rmap] |
523 | 526 | (if gfn |
524 | 527 | (gfn) |
|
863 | 866 | (c/or (nil? vseq) (= i limit)) x |
864 | 867 | (valid? spec v) (recur (inc i) vs) |
865 | 868 | :else ::invalid))))))) |
866 | | - (unform* [_ x] x) |
| 869 | + (unform* [_ x] |
| 870 | + (if conform-all |
| 871 | + (let [spec @spec |
| 872 | + [init add complete] (cfns x)] |
| 873 | + (loop [ret (init x), i 0, [v & vs :as vseq] (seq x)] |
| 874 | + (if (>= i (c/count x)) |
| 875 | + (complete ret) |
| 876 | + (recur (add ret i v (unform* spec v)) (inc i) vs)))) |
| 877 | + x)) |
867 | 878 | (explain* [_ path via in x] |
868 | 879 | (c/or (coll-prob x kind kind-form distinct count min-count max-count |
869 | 880 | path via in) |
|
1089 | 1100 | (case op |
1090 | 1101 | ::accept nil |
1091 | 1102 | nil p |
1092 | | - ::amp (list* 'clojure.spec/& (op-describe p1) forms) |
| 1103 | + ::amp (list* 'clojure.spec.alpha/& (op-describe p1) forms) |
1093 | 1104 | ::pcat (if rep+ |
1094 | 1105 | (list `+ rep+) |
1095 | 1106 | (cons `cat (mapcat vector (c/or (seq ks) (repeat :_)) forms))) |
|
1106 | 1117 | insufficient (fn [path form] |
1107 | 1118 | [{:path path |
1108 | 1119 | :reason "Insufficient input" |
1109 | | - :pred (abbrev form) |
| 1120 | + :pred form |
1110 | 1121 | :val () |
1111 | 1122 | :via via |
1112 | 1123 | :in in}])] |
|
1218 | 1229 | (op-explain (op-describe p) p path via (conj in i) (seq data)) |
1219 | 1230 | [{:path path |
1220 | 1231 | :reason "Extra input" |
1221 | | - :pred (abbrev (op-describe re)) |
| 1232 | + :pred (op-describe re) |
1222 | 1233 | :val data |
1223 | 1234 | :via via |
1224 | 1235 | :in (conj in i)}]) |
1225 | 1236 | (c/or (op-explain (op-describe p) p path via (conj in i) (seq data)) |
1226 | 1237 | [{:path path |
1227 | 1238 | :reason "Extra input" |
1228 | | - :pred (abbrev (op-describe p)) |
| 1239 | + :pred (op-describe p) |
1229 | 1240 | :val data |
1230 | 1241 | :via via |
1231 | 1242 | :in (conj in i)}])))))) |
|
1247 | 1258 | (explain* [_ path via in x] |
1248 | 1259 | (if (c/or (nil? x) (coll? x)) |
1249 | 1260 | (re-explain path via in re (seq x)) |
1250 | | - [{:path path :pred (abbrev (op-describe re)) :val x :via via :in in}])) |
| 1261 | + [{:path path :pred (op-describe re) :val x :via via :in in}])) |
1251 | 1262 | (gen* [_ overrides path rmap] |
1252 | 1263 | (if gfn |
1253 | 1264 | (gfn) |
|
1389 | 1400 | (c/and (<= (inst-ms start) t) (< t (inst-ms end)))))) |
1390 | 1401 |
|
1391 | 1402 | (defn int-in-range? |
1392 | | - "Return true if start <= val and val < end" |
| 1403 | + "Return true if start <= val, val < end and val is a fixed |
| 1404 | + precision integer." |
1393 | 1405 | [start end val] |
1394 | 1406 | (cond |
1395 | 1407 | (integer? val) (c/and (<= start val) (< val end)) |
|
0 commit comments