@@ -6,22 +6,31 @@ import kotlin.collections.HashMap
6
6
public typealias HookContext = HashMap <String , Any >
7
7
8
8
public open class Interceptors <F : Function <* >> {
9
- // TODO: I don't love that I've really only made [taps] immutable.. this screams inconsistency
10
- public val register: MutableList < (TapInfo <F >) -> TapInfo <F >? > = mutableListOf ()
11
- public val tap: MutableList < (HookContext , TapInfo <F >) -> Unit > = mutableListOf ()
12
- public val call: MutableList <F > = mutableListOf ()
13
-
14
- public fun invokeRegisterInterceptors (info : TapInfo <F >? ): TapInfo <F >? =
15
- register.fold(info) { acc, interceptor ->
16
- acc?.let (interceptor)
17
- }
9
+ public var register: List < (TapInfo <F >) -> TapInfo <F >? > = emptyList(); private set
10
+ public var tap: List < (HookContext , TapInfo <F >) -> Unit > = emptyList(); private set
11
+ public var call: List <F > = emptyList(); private set
12
+
13
+ public fun addRegisterInterceptor (interceptor : (TapInfo <F >) -> TapInfo <F >? ) {
14
+ register = register + interceptor
15
+ }
16
+
17
+ public fun invokeRegisterInterceptors (info : TapInfo <F >? ): TapInfo <F >? = register.fold(info) { acc, interceptor ->
18
+ acc?.let (interceptor)
19
+ }
18
20
19
- public fun invokeTapInterceptors (taps : List <TapInfo <F >>, context : HookContext ): Unit =
20
- tap.forEach { interceptor ->
21
- taps.forEach { tap ->
22
- interceptor.invoke(context, tap)
23
- }
21
+ public fun addTapInterceptor (interceptor : (HookContext , TapInfo <F >) -> Unit ) {
22
+ tap = tap + interceptor
23
+ }
24
+
25
+ public fun invokeTapInterceptors (taps : List <TapInfo <F >>, context : HookContext ): Unit = tap.forEach { interceptor ->
26
+ taps.forEach { tap ->
27
+ interceptor.invoke(context, tap)
24
28
}
29
+ }
30
+
31
+ public fun addCallInterceptor (interceptor : F ) {
32
+ call = call + interceptor
33
+ }
25
34
}
26
35
27
36
public class TapInfo <FWithContext : Function <* >> internal constructor(
@@ -65,37 +74,53 @@ public abstract class BaseHook<F : Function<*>>(private val type: String) {
65
74
protected var taps: List <TapInfo <F >> = emptyList(); private set
66
75
protected open val interceptors: Interceptors <F > = Interceptors ()
67
76
68
- public fun tap (name : String , f : F ): String = tap(name, randomId(), f)
69
-
70
- public fun tap (name : String , id : String , f : F ): String {
71
- val filtered = taps.filter {
72
- it.id != id
73
- }
74
-
75
- taps = TapInfo (name, id, type, f).let (interceptors::invokeRegisterInterceptors)?.let {
76
- filtered + it
77
- } ? : filtered
78
-
79
- return id
77
+ /* *
78
+ * Tap the hook with [f].
79
+ *
80
+ * @param name human-readable identifier to make debugging easier
81
+ *
82
+ * @return an auto generated identifier token that can be used to [untap], null if tap was
83
+ * rejected by any of the register interceptors.
84
+ */
85
+ public fun tap (name : String , f : F ): String? = tap(name, generateRandomId(), f)
86
+
87
+ /* *
88
+ * Tap the hook with [f].
89
+ *
90
+ * @param name human-readable identifier to make debugging easier
91
+ * @param id identifier token to register the [f] callback with. If another tap exists with
92
+ * the same [id], it will be overridden, which essentially shortcuts an [untap] call.
93
+ *
94
+ * @return identifier token that can be used to [untap], null if tap was rejected by any of the
95
+ * register interceptors.
96
+ */
97
+ public fun tap (name : String , id : String , f : F ): String? {
98
+ untap(id)
99
+
100
+ return TapInfo (name, id, type, f).let (interceptors::invokeRegisterInterceptors)?.also {
101
+ taps = taps + it
102
+ }?.id
80
103
}
81
104
105
+ /* * Remove tapped callback associated with the [id] returned from [tap] */
82
106
public fun untap (id : String ) {
83
107
taps = taps.filter {
84
108
it.id != id
85
109
}
86
110
}
87
111
88
112
public fun interceptTap (f : (context: HookContext , tapInfo: TapInfo <F >) -> Unit ) {
89
- interceptors.tap.add (f)
113
+ interceptors.addTapInterceptor (f)
90
114
}
91
115
92
116
public fun interceptCall (f : F ) {
93
- interceptors.call.add (f)
117
+ interceptors.addCallInterceptor (f)
94
118
}
95
119
96
120
public fun interceptRegister (f : (TapInfo <F >) -> TapInfo <F >? ) {
97
- interceptors.register.add (f)
121
+ interceptors.addRegisterInterceptor (f)
98
122
}
99
- }
100
123
101
- public fun randomId (): String = UUID .randomUUID().toString()
124
+ /* * Method to generate a random identifier for managing `TapInfo`s */
125
+ protected open fun generateRandomId (): String = UUID .randomUUID().toString()
126
+ }
0 commit comments