Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
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
81 changes: 71 additions & 10 deletions core/shared/src/main/scala/zio/Has.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,78 @@ object Has {
"operator, you must ensure the service produced by your layer is " +
"wrapped in Has."
)
trait AreHas[-R, -R1] {
def union[R0 <: R, R00 <: R1: Tag](r: R0, r1: R00): R0 with R00
def unionAll[R0 <: R, R00 <: R1](r: R0, r1: R00): R0 with R00
trait Union[R, R1] {
def union(r: R, r1: R1): R with R1
}
object AreHas {
implicit def ImplicitAre[R <: Has[_], R1 <: Has[_]]: AreHas[R, R1] =
new AreHas[R, R1] {
def union[R0 <: R, R00 <: R1: Tag](r: R0, r1: R00): R0 with R00 =
r.union[R00](r1)
def unionAll[R0 <: R, R00 <: R1](r: R0, r1: R00): R0 with R00 =
r.unionAll[R00](r1)
object Union extends LowPriorityUnionImplicits {
implicit def HasHasUnion[R <: Has[_], R1 <: Has[_]: Tag]: Union[R, R1] =
new Union[R, R1] {
def union(r: R, r1: R1): R with R1 =
r.union[R1](r1)
}
}
trait LowPriorityUnionImplicits {
implicit def HasAnyUnion[R <: Has[_]]: Union[R, Any] =
new Union[R, Any] {
def union(r: R, r1: Any): R = {
val _ = r1
r
}
}
implicit def AnyHasUnion[R1 <: Has[_]]: Union[Any, R1] =
new Union[Any, R1] {
def union(r: Any, r1: R1): R1 = {
val _ = r
r1
}
}
implicit val AnyAnyUnion: Union[Any, Any] =
new Union[Any, Any] {
def union(r: Any, r1: Any): Any = {
val _ = (r, r1)
()
}
}
}

@implicitNotFound(
"The ZLayer operator you are trying to use needs to combine multiple " +
"services. While services cannot directly be combined, they can be " +
"combined if first wrapped in the Has data type. Before you use this " +
"operator, you must ensure the service produced by your layer is " +
"wrapped in Has."
)
trait UnionAll[R, R1] {
def unionAll(r: R, r1: R1): R with R1
}
object UnionAll extends LowPriorityUnionAllImplicits {
implicit def HasHasUnionAll[R <: Has[_], R1 <: Has[_]: Tag]: UnionAll[R, R1] =
new UnionAll[R, R1] {
def unionAll(r: R, r1: R1): R with R1 =
r.unionAll[R1](r1)
}
}
trait LowPriorityUnionAllImplicits {
implicit def HasAnyUnionAll[R <: Has[_]]: UnionAll[R, Any] =
new UnionAll[R, Any] {
def unionAll(r: R, r1: Any): R = {
val _ = r1
r
}
}
implicit def AnyHasUnionAll[R1 <: Has[_]]: UnionAll[Any, R1] =
new UnionAll[Any, R1] {
def unionAll(r: Any, r1: R1): R1 = {
val _ = r
r1
}
}
implicit val AnyAnyUnionAll: UnionAll[Any, Any] =
new UnionAll[Any, Any] {
def unionAll(r: Any, r1: Any): Any = {
val _ = (r, r1)
()
}
}
}

Expand Down
24 changes: 12 additions & 12 deletions core/shared/src/main/scala/zio/ZLayer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ import zio.internal.Platform
*/
sealed trait ZLayer[-RIn, +E, +ROut] { self =>

final def +!+[E1 >: E, RIn2, ROut2](
final def +!+[E1 >: E, RIn2, ROut1 >: ROut, ROut2](
that: ZLayer[RIn2, E1, ROut2]
)(implicit ev: Has.AreHas[ROut, ROut2]): ZLayer[RIn with RIn2, E1, ROut with ROut2] =
self.zipWithPar(that)(ev.unionAll[ROut, ROut2])
)(implicit ev: Has.UnionAll[ROut1, ROut2]): ZLayer[RIn with RIn2, E1, ROut1 with ROut2] =
self.zipWithPar(that)(ev.unionAll)

/**
* Combines this layer with the specified layer, producing a new layer that
* has the inputs of both layers, and the outputs of both layers.
*/
final def ++[E1 >: E, RIn2, ROut1 >: ROut, ROut2](
that: ZLayer[RIn2, E1, ROut2]
)(implicit ev: Has.AreHas[ROut1, ROut2], tag: Tag[ROut2]): ZLayer[RIn with RIn2, E1, ROut1 with ROut2] =
self.zipWithPar(that)(ev.union[ROut1, ROut2])
)(implicit ev: Has.Union[ROut1, ROut2], tag: Tag[ROut2]): ZLayer[RIn with RIn2, E1, ROut1 with ROut2] =
self.zipWithPar(that)(ev.union)

/**
* A symbolic alias for `zipPar`.
Expand All @@ -73,8 +73,8 @@ sealed trait ZLayer[-RIn, +E, +ROut] { self =>
*/
final def >+>[E1 >: E, RIn2 >: ROut, ROut1 >: ROut, ROut2](
that: ZLayer[RIn2, E1, ROut2]
)(implicit ev: Has.AreHas[ROut1, ROut2], tagged: Tag[ROut2]): ZLayer[RIn, E1, ROut1 with ROut2] =
self ++ (self >>> that)
)(implicit ev: Has.Union[ROut1, ROut2], tagged: Tag[ROut2]): ZLayer[RIn, E1, ROut1 with ROut2] =
self.++[E1, RIn, ROut1, ROut2](self >>> that)

/**
* Feeds the output services of this layer into the input of the specified
Expand All @@ -89,16 +89,16 @@ sealed trait ZLayer[-RIn, +E, +ROut] { self =>
*/
final def and[E1 >: E, RIn2, ROut1 >: ROut, ROut2](
that: ZLayer[RIn2, E1, ROut2]
)(implicit ev: Has.AreHas[ROut1, ROut2], tagged: Tag[ROut2]): ZLayer[RIn with RIn2, E1, ROut1 with ROut2] =
self ++ that
)(implicit ev: Has.Union[ROut1, ROut2], tagged: Tag[ROut2]): ZLayer[RIn with RIn2, E1, ROut1 with ROut2] =
self.++[E1, RIn2, ROut1, ROut2](that)

/**
* A named alias for `>+>`.
*/
final def andTo[E1 >: E, RIn2 >: ROut, ROut1 >: ROut, ROut2](
that: ZLayer[RIn2, E1, ROut2]
)(implicit ev: Has.AreHas[ROut1, ROut2], tagged: Tag[ROut2]): ZLayer[RIn, E1, ROut1 with ROut2] =
self >+> that
)(implicit ev: Has.Union[ROut1, ROut2], tagged: Tag[ROut2]): ZLayer[RIn, E1, ROut1 with ROut2] =
self.>+>[E1, RIn2, ROut1, ROut2](that)

/**
* Builds a layer into a managed value.
Expand Down Expand Up @@ -2189,7 +2189,7 @@ object ZLayer {
* Returns a new layer that produces the outputs of this layer but also
* passes through the inputs to this layer.
*/
def passthrough(implicit ev: Has.AreHas[RIn, ROut], tag: Tag[ROut]): ZLayer[RIn, E, RIn with ROut] =
def passthrough(implicit ev: Has.Union[RIn, ROut], tag: Tag[ROut]): ZLayer[RIn, E, RIn with ROut] =
ZLayer.identity[RIn] ++ self
}

Expand Down