-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.clj
56 lines (46 loc) · 1.42 KB
/
core.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
(ns error-helpers.core)
(defmacro err-let [err-fn bindings & body]
(cond
(odd? (count bindings))
(throw (IllegalArgumentException. (str bindings " number of bindings must be even")))
(zero? (count bindings))
`(do ~@body)
(nil? err-fn)
`(let* ~(destructure bindings) ~@body)
:else
`(let [b1# ~(bindings 1)]
(if (some? (~err-fn b1#))
b1#
(let [~(bindings 0) b1#]
(err-let ~err-fn ~(subvec bindings 2) ~@body))))))
(defmacro if-pred [pred? bindings then else]
(when (not= 2 (count bindings)) (throw (IllegalArgumentException. (str bindings " number of bindings must be 2"))))
(let [form (bindings 0) tst (bindings 1)]
`(let [t# ~tst]
(if (~pred? t#)
(let [~form t#]
~then)
~else))))
(defmacro default-to [operation default-value]
`(try
~operation
(catch Exception e#
~default-value)))
(defn thread-calls [err-key calls init-arg]
{:pre [(not (empty? calls))]}
(loop [[c & cs] calls result init-arg]
(cond
(some? (get result err-key))
result
(nil? c)
result
:else
(recur cs (c result)))))
(defn first-non-error-choice [err-key pick-fn choices]
(loop [[choice & cs] choices errors []]
(if (nil? choice)
{err-key errors}
(let [result (pick-fn (choice))]
(if-some [err (get result err-key)]
(recur cs (conj errors err))
result)))))