diff --git a/zio-interop-cats-tests/shared/src/test/scala/zio/interop/CatsMtlSpec.scala b/zio-interop-cats-tests/shared/src/test/scala/zio/interop/CatsMtlSpec.scala index 1f585aa7..696bc4df 100644 --- a/zio-interop-cats-tests/shared/src/test/scala/zio/interop/CatsMtlSpec.scala +++ b/zio-interop-cats-tests/shared/src/test/scala/zio/interop/CatsMtlSpec.scala @@ -21,6 +21,20 @@ class CatsMtlSpec extends ZioSpecBase { implicit tc => LocalTests[ZIO[Ctx, Error, _], ZEnvironment[Ctx]].local[ZEnvironment[Ctx], Int] ) + Unsafe.unsafe { implicit unsafe => + implicit val f: FiberRef[Ctx] = FiberRef.unsafe.make("") + + checkAllAsync( + "FiberRef Ask[ZIO[Ctx, Error, _]]", + implicit tc => AskTests[ZIO[Ctx, Error, _], Ctx].ask[Ctx] + ) + + checkAllAsync( + "FiberRef Local[ZIO[Ctx, Error, _]]", + implicit tc => LocalTests[ZIO[Ctx, Error, _], Ctx].local[Ctx, Int] + ) + } + checkAllAsync( "Raise[ZIO[Ctx, Error, _]]", implicit tc => RaiseTests[ZIO[Ctx, Error, _], Error].raise[Int] diff --git a/zio-interop-cats/shared/src/main/scala/zio/interop/catsmtl.scala b/zio-interop-cats/shared/src/main/scala/zio/interop/catsmtl.scala index 83f5d872..9df3f419 100644 --- a/zio-interop-cats/shared/src/main/scala/zio/interop/catsmtl.scala +++ b/zio-interop-cats/shared/src/main/scala/zio/interop/catsmtl.scala @@ -18,7 +18,7 @@ package zio.interop import cats.Applicative import cats.mtl.* -import zio.{ CanFail, ZEnvironment, ZIO } +import zio.{ CanFail, FiberRef, ZEnvironment, ZIO } import zio.internal.stacktracer.InteropTracer abstract class CatsMtlPlatform extends CatsMtlInstances @@ -47,4 +47,21 @@ abstract class CatsMtlInstances { fa.catchAll(f)(implicitly[CanFail[E]], InteropTracer.newTrace(f)) } + implicit def fiberRefLocal[R, E](implicit + fiberRef: FiberRef[R], + ev: Applicative[ZIO[R, E, _]] + ): Local[ZIO[R, E, _], R] = new Local[ZIO[R, E, _], R] { + override def local[A](fa: ZIO[R, E, A])(f: R => R): ZIO[R, E, A] = fiberRef.locallyWith(f)(fa) + + override def applicative: Applicative[ZIO[R, E, *]] = ev + + override def ask[E2 >: R]: ZIO[R, E, E2] = fiberRef.get + } + + implicit def fiberRefAsk[R, E](implicit fiberRef: FiberRef[R], ev: Applicative[ZIO[R, E, _]]): Ask[ZIO[R, E, _], R] = + new Ask[ZIO[R, E, _], R] { + override def applicative: Applicative[ZIO[R, E, *]] = ev + override def ask[E2 >: R]: ZIO[R, E, E2] = fiberRef.get + } + }