-
Notifications
You must be signed in to change notification settings - Fork 0
/
ref_path.cljc
88 lines (71 loc) · 1.91 KB
/
ref_path.cljc
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
(ns slip.data.ref-path
(:require
#?(:clj [clojure.pprint :as pprint])
[slip.data.protocols :as p]
[a-frame.interceptor-chain.data.protocols :as ic.d.p]
[taoensso.timbre :refer [info warn]]))
;; don't know why, but cljs compile doesn't agree
;; with deftype here - perhaps some
;; interaction with the tag-readers
(defrecord RefPath [path maybe?]
ic.d.p/IResolveData
(-resolve-data [_spec interceptor-ctx]
(let [data (get-in
interceptor-ctx
(into [:slip/system] path))]
(when (and (not maybe?)
(nil? data))
(throw
(ex-info "nil ref" {:path path
:system (get interceptor-ctx :slip/system)})))
data))
p/ICollectRefs
(-collect-refs [spec refs]
(conj refs spec))
p/IRefPath
(-path [_] path))
(defn ref-path
[v]
(cond
(sequential? v)
(->RefPath (into [] v) false)
(keyword? v)
(->RefPath [v] false)
:else
(throw (ex-info "unknown RefPath" {:ref-path v}))))
(defn maybe-ref-path
[v]
(cond
(sequential? v)
(->RefPath (into [] v) true)
(keyword? v)
(->RefPath [v] true)
:else
(throw (ex-info "unknown RefPath" {:ref-path v}))))
(defn ref-path?
[o]
(instance? RefPath o))
(defn path
[o]
(p/-path o))
#?(:clj
(defn print-ref-path
[ref-path ^java.io.Writer w]
(.write w "#slip/ref ")
(print-method (p/-path ref-path) w)))
#?(:clj
(defmethod print-method RefPath [this ^java.io.Writer w]
(print-ref-path this w)))
#?(:clj
(defmethod print-dup RefPath [this ^java.io.Writer w]
(print-ref-path this w)))
#?(:clj
(.addMethod pprint/simple-dispatch
RefPath
(fn [ref-path]
(print-ref-path ref-path *out*))))
#?(:cljs
(extend-protocol IPrintWithWriter
RefPath
(-pr-writer [ref-path writer _]
(write-all writer "#slip/ref " (p/-path ref-path) ""))))