-
Notifications
You must be signed in to change notification settings - Fork 93
/
util.clj
94 lines (80 loc) · 2.26 KB
/
util.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
(ns ^:no-doc etaoin.impl.util
(:require [lambdaisland.uri :as uri])
(:import
[java.io File IOException]
[java.net InetSocketAddress ServerSocket Socket]))
(set! *warn-on-reflection* true)
(defn map-or-nil?
[x]
(or (map? x) (nil? x)))
(defn deep-merge
[& vals]
(if (every? map-or-nil? vals)
(apply merge-with deep-merge vals)
(if (every? sequential? vals)
(apply concat vals)
(last vals))))
(defmacro defmethods
"Declares multimethods in batch. For each dispatch value from
dispatch-vals, creates a new method."
[multifn dispatch-vals & fn-tail]
`(doseq [dispatch-val# ~dispatch-vals]
(defmethod ~multifn dispatch-val# ~@fn-tail)))
(defn sec->ms [sec]
(* sec 1000))
(defn ms->sec [ms]
(/ ms 1000))
(defn dispatch-types
[& args]
(mapv class args))
(defn error
([msg]
(throw (Exception. ^String msg)))
([tpl & args]
(error (apply format tpl args))))
(defn get-free-port []
(let [socket (ServerSocket. 0)]
(.close socket)
(.getLocalPort socket)))
(defn connectable?
"Returns `true` when it is possible to connect a given `host` over `port`."
[host port]
(with-open [socket (Socket.)]
(try
(.connect socket (InetSocketAddress. ^String host ^int port) 1000)
true
(catch IOException _e
false))))
(defn exit
[code template & args]
(let [out (if (zero? code)
*out*
*err*)]
(binding [*out* out]
(println (apply format
template args))))
(System/exit code))
(defmacro with-tmp-file [prefix suffix bind & body]
`(let [tmp# (File/createTempFile ~prefix ~suffix)
~bind (.getAbsolutePath tmp#)]
(try
~@body
(finally
(.delete tmp#)))))
(defn strip-url-creds
"Return `url` with any http credentials stripped, https://user:pass@hello.com -> https://hello.com.
Use when logging urls to avoid spilling secrets."
^String [^String url]
(-> url
uri/parse
(dissoc :user :password)
uri/uri-str))
(defn assoc-some
"Associates a key with a value in a map, if and only if the value is
not nil. From medley."
([m k v]
(if (nil? v) m (assoc m k v)))
([m k v & kvs]
(reduce (fn [m [k v]] (assoc-some m k v))
(assoc-some m k v)
(partition 2 kvs))))