Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move FiberLocal.apply to IO.fiberLocal #1827

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions core/shared/src/main/scala/cats/effect/FiberLocal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,3 @@ trait FiberLocal[F[_], A] {
def getAndClear: F[A]

}

object FiberLocal {

def apply[A](default: A): IO[FiberLocal[IO, A]] =
IO {
new FiberLocal[IO, A] { self =>
override def get: IO[A] =
IO.Local(state => (state, state.get(self).map(_.asInstanceOf[A]).getOrElse(default)))

override def set(value: A): IO[Unit] =
IO.Local(state => (state + (self -> value), ()))

override def clear: IO[Unit] =
IO.Local(state => (state - self, ()))

override def update(f: A => A): IO[Unit] =
get.flatMap(a => set(f(a)))

override def modify[B](f: A => (A, B)): IO[B] =
get.flatMap { a =>
val (a2, b) = f(a)
set(a2).as(b)
}

override def getAndSet(value: A): IO[A] =
get <* set(value)

override def getAndClear: IO[A] =
get <* clear

}
}

}
29 changes: 29 additions & 0 deletions core/shared/src/main/scala/cats/effect/IO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,35 @@ object IO extends IOCompanionPlatform with IOLowPriorityImplicits {

def deferred[A]: IO[Deferred[IO, A]] = IO(Deferred.unsafe)

def fiberLocal[A](default: A): IO[FiberLocal[IO, A]] =
IO {
new FiberLocal[IO, A] { self =>
override def get: IO[A] =
IO.Local(state => (state, state.get(self).map(_.asInstanceOf[A]).getOrElse(default)))

override def set(value: A): IO[Unit] =
IO.Local(state => (state + (self -> value), ()))

override def clear: IO[Unit] =
IO.Local(state => (state - self, ()))

override def update(f: A => A): IO[Unit] =
get.flatMap(a => set(f(a)))

override def modify[B](f: A => (A, B)): IO[B] =
get.flatMap { a =>
val (a2, b) = f(a)
set(a2).as(b)
}

override def getAndSet(value: A): IO[A] =
get <* set(value)

override def getAndClear: IO[A] =
get <* clear
}
}

def bracketFull[A, B](acquire: Poll[IO] => IO[A])(use: A => IO[B])(
release: (A, OutcomeIO[B]) => IO[Unit]): IO[B] = {
val safeRelease: (A, OutcomeIO[B]) => IO[Unit] =
Expand Down
14 changes: 7 additions & 7 deletions tests/shared/src/test/scala/cats/effect/FiberLocalSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ package effect

class FiberLocalSpec extends BaseSpec {

"Local" should {
"FiberLocal" should {
"return a default value" in ticked { implicit ticker =>
val io = FiberLocal(0).flatMap(_.get)
val io = IO.fiberLocal(0).flatMap(_.get)

io must completeAs(0)
}

"set and get a value" in ticked { implicit ticker =>
val io = for {
local <- FiberLocal(0)
local <- IO.fiberLocal(0)
_ <- local.set(10)
value <- local.get
} yield value
Expand All @@ -38,7 +38,7 @@ class FiberLocalSpec extends BaseSpec {

"preserve locals across async boundaries" in ticked { implicit ticker =>
val io = for {
local <- FiberLocal(0)
local <- IO.fiberLocal(0)
_ <- local.set(10)
_ <- IO.cede
value <- local.get
Expand All @@ -49,7 +49,7 @@ class FiberLocalSpec extends BaseSpec {

"copy locals to children fibers" in ticked { implicit ticker =>
val io = for {
local <- FiberLocal(0)
local <- IO.fiberLocal(0)
_ <- local.set(10)
f <- local.get.start
value <- f.joinWithNever
Expand All @@ -60,7 +60,7 @@ class FiberLocalSpec extends BaseSpec {

"child local manipulation is invisible to parents" in ticked { implicit ticker =>
val io = for {
local <- FiberLocal(10)
local <- IO.fiberLocal(10)
f <- local.set(20).start
_ <- f.join
value <- local.get
Expand All @@ -71,7 +71,7 @@ class FiberLocalSpec extends BaseSpec {

"parent local manipulation is invisible to children" in ticked { implicit ticker =>
val io = for {
local <- FiberLocal(0)
local <- IO.fiberLocal(0)
d1 <- Deferred[IO, Unit]
f <- (d1.get *> local.get).start
_ <- local.set(10)
Expand Down