Skip to content

Instantly share code, notes, and snippets.

@fokot
Last active December 13, 2019 15:25
Show Gist options
  • Save fokot/5d7425997393b4e77a73e6777790fa84 to your computer and use it in GitHub Desktop.
Save fokot/5d7425997393b4e77a73e6777790fa84 to your computer and use it in GitHub Desktop.
ZIO workshop
package com.upstartcommerce.rating
import zio.ZIO
import zio.console.Console
object MiniTest extends zio.App {
trait GetUser {
def user: User
}
case class User(name: String)
type Environment = Console with GetUser
val printAAA: ZIO[Console, Throwable, Unit] =
ZIO.accessM[Console](_.console.putStrLn("AAA"))
def printUser(u: User): ZIO[Console, Throwable, Unit] =
ZIO.accessM[Console](_.console.putStrLn(u.name))
val printUserZIO: ZIO[Environment, Throwable, Unit] =
ZIO.accessM[Environment](
e => e.console.putStrLn(e.user.name))
override def run(args: List[String]): ZIO[zio.ZEnv, Nothing, Int] =
(for {
_ <- printAAA
_ <- printUser(User("Gordon"))
_ <- printUserZIO
} yield ()).provideSome[zio.ZEnv](
env => new Console with GetUser {
override val console: Console.Service[Any] = env.console
override def user: User = User("Yan")
}
).orDie as 0
}
import zio.{RIO, Task}
object ZioDependencies {
/************* AUTH *************/
trait Auth {
def auth: Auth.Service
}
object Auth {
trait Service {
def token: Task[String]
}
// this is useful so I do not need to repeat myself in provide
trait HeaderAuth extends Auth {
override def auth: Service = HeaderAuthService
}
object HeaderAuthService extends Service {
override def token: Task[String] = ???
}
}
/************* Storage *************/
trait Storage[R] {
def storage: Storage.Service[R]
}
object Storage {
trait Service[R] {
def get(id: Int): RIO[R, String]
}
}
object LiveStorage extends Storage.Service[Auth] {
override def get(id: Int): RIO[Auth, String] = ???
}
object TestStorage extends Storage.Service[Any] {
override def get(id: Int): RIO[Any, String] = ???
}
/************* ExternalSystem *************/
trait ExternalSystem {
// here must be all deps
def externalSystem: ExternalSystem.Service[Auth]
}
object ExternalSystem {
trait Service[-R] {
def get(id: Int): RIO[R, String]
}
}
object LiveExternalSystem extends ExternalSystem.Service[Auth] {
override def get(id: Int): RIO[Auth, String] = ???
}
object TestExternalSystem extends ExternalSystem.Service[Any] {
override def get(id: Int): RIO[Any, String] = ???
}
/************* Prod dependencies *************/
val prodZio: RIO[Auth with Storage[Auth] with ExternalSystem, Int] = ???
prodZio.provide(
new Auth with Storage[Auth] with ExternalSystem {
override def auth: Auth.Service = Auth.HeaderAuthService
override def storage: Storage.Service[Auth] = LiveStorage
override def externalSystem: ExternalSystem.Service[Auth] = LiveExternalSystem
}
)
prodZio.provide(
new Storage[Auth] with ExternalSystem with Auth.HeaderAuth {
override def storage: Storage.Service[Auth] = LiveStorage
override def externalSystem: ExternalSystem.Service[Auth] = LiveExternalSystem
}
)
/************* Test dependencies *************/
val testZio: RIO[Auth with Storage[Any] with ExternalSystem, Int] = ???
testZio.provide(
new Auth with Storage[Any] with ExternalSystem {
override def auth: Auth.Service = Auth.HeaderAuthService
override def storage: Storage.Service[Any] = TestStorage
override def externalSystem: ExternalSystem.Service[Auth] = TestExternalSystem
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment