-
Notifications
You must be signed in to change notification settings - Fork 2
/
HotswapRefConstructor.scala
48 lines (41 loc) · 1.74 KB
/
HotswapRefConstructor.scala
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
package io.janstenpickle.hotswapref
import cats.effect.kernel.{Concurrent, Resource}
/** Use some `I` to construct `R` via a provided function, within a [[HotswapRef]].
*
* Calls to [[swapWith]] update the value of `R` within [[HotswapRef]] with provided with some `I`.
*/
trait HotswapRefConstructor[F[_], I, R] extends HotswapRef[F, (I, R)] {
protected def func: I => Resource[F, R]
/** Swap `R` using `I` using some function of `I` to [[cats.effect.kernel.Resource]] of `R`, provided at construction
* time
*/
def swapWith(next: I): F[Unit] = swap(func(next).map(next -> _))
/** Access the current input value `I` on its own
*/
def accessI: Resource[F, I] = access.map(_._1)
/** Access the current resource value `R` on its own
*/
def accessR: Resource[F, R] = access.map(_._2)
}
object HotswapRefConstructor {
/** Creates a new [[HotswapRefConstructor]] initialized using `initial` and `make`. The [[HotswapRefConstructor]]
* instance is returned within a [[cats.effect.kernel.Resource]].
*
* @param initial
* the initial value of input `I` to be used to construct `R`
* @param make
* used to construct a [[cats.effect.kernel.Resource]] of `R` from `I`, called on construction and when `swapWith`
* is used.
*/
def apply[F[_]: Concurrent, I, R](
initial: I
)(make: I => Resource[F, R]): Resource[F, HotswapRefConstructor[F, I, R]] = {
HotswapRef[F, (I, R)](make(initial).map(initial -> _)).map { hotswap =>
new HotswapRefConstructor[F, I, R] {
override protected val func: I => Resource[F, R] = make
override def swap(next: Resource[F, (I, R)]): F[Unit] = hotswap.swap(next)
override val access: Resource[F, (I, R)] = hotswap.access
}
}
}
}