zio.magic.macros.LayerMacros.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zio-magic-macros_2.13 Show documentation
Show all versions of zio-magic-macros_2.13 Show documentation
Magically construct ZLayers at compile-time (with friendly errors)
The newest version!
package zio.magic.macros
import zio._
import zio.magic.macros.graph.Node
import zio.magic.macros.utils.{CleanCodePrinter, LayerMacroUtils}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
private[zio] class LayerMacros(val c: blackbox.Context) extends LayerMacroUtils {
import c.universe._
def injectImpl[F[_, _, _], R: c.WeakTypeTag, E, A](
layers: c.Expr[ZLayer[_, E, _]]*
): c.Expr[F[Any, E, A]] = {
assertProperVarArgs(layers)
val expr = buildMemoizedLayer(generateExprGraph(layers), getRequirements[R])
c.Expr[F[Any, E, A]](q"${c.prefix}.provideLayerManual(${expr.tree})")
}
def injectSomeImpl[F[_, _, _], R0: c.WeakTypeTag, R: c.WeakTypeTag, E, A](
layers: c.Expr[ZLayer[_, E, _]]*
): c.Expr[F[R0, E, A]] = {
assertProperVarArgs(layers)
val remainderRequirements = getRequirements[R0]
val remainderExpr =
if (weakTypeOf[R0] =:= weakTypeOf[ZEnv]) reify(ZEnv.any)
else reify(ZLayer.requires[R0])
val remainderNode = Node(List.empty, remainderRequirements, remainderExpr)
val nodes = (remainderNode +: layers.map(getNode)).toList
val layerExpr = buildMemoizedLayer(generateExprGraph(nodes), getRequirements[R])
c.Expr[F[R0, E, A]](q"${c.prefix}.provideLayerManual(${layerExpr.tree})")
}
def debugGetRequirements[R: c.WeakTypeTag]: c.Expr[List[String]] =
c.Expr[List[String]](q"${getRequirements[R]}")
def debugShowTree(any: c.Tree): c.Expr[String] = {
val string = CleanCodePrinter.show(c)(any)
c.Expr[String](q"$string")
}
}
private[zio] object MacroUnitTestUtils {
def getRequirements[R]: List[String] = macro LayerMacros.debugGetRequirements[R]
def showTree(any: Any): String = macro LayerMacros.debugShowTree
}