Skip to content

Instantly share code, notes, and snippets.

@trbngr
Last active August 27, 2016 21:28
Show Gist options
  • Select an option

  • Save trbngr/3ac66c1facd0be3bdd6b4fb89a2bee5a to your computer and use it in GitHub Desktop.

Select an option

Save trbngr/3ac66c1facd0be3bdd6b4fb89a2bee5a to your computer and use it in GitHub Desktop.
import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.ExecutionContext.Implicits.global
object ModelReaders {
implicit object UserReader extends ModelReader[User] {
def read(repo: Repo, id: Int) = repo.getUser(id)
}
implicit object RoomReader extends ModelReader[Room] {
def read(repo: Repo, id: Int): Future[Option[Room]] = repo.getRoom(id)
}
}
object Application extends App {
import SomeObjectThatShouldNotRequireExecutionContext._
val ctx = new ContextImpl(new Repo)
UserType.resolve(ctx) map println
Thread.sleep(5000)
}
case class ObjectType[Ctx](resolve: Ctx => Future[Option[Any]])
object SomeObjectThatShouldNotRequireExecutionContext {
import ModelReaders._
lazy val UserType = ObjectType[Context](ctx => {
val userProjection = ctx.readModel[User](56)
userProjection { user => ProjectedThing(user.id) }
})
}
case class ProjectedThing(id: Int)
case class User(id: Int)
case class Room(id: Int)
trait ModelReader[A] {
def read(repo: Repo, id: Int): Future[Option[A]]
}
trait Context {
def readModel[A: ModelReader](id: Int): ModelProjection[A]
final class ModelProjection[A](entity: Future[Option[A]]) {
def apply[B](projection: A => B): Future[Option[B]] = entity map {
case Some(e) => Some(projection(e))
case _ => None
}
}
}
class ContextImpl(repo: Repo)(implicit ec: ExecutionContext) extends Context {
def readModel[A: ModelReader](id: Int): ModelProjection[A] = {
new ModelProjection[A](implicitly[ModelReader[A]].read(repo, id))
}
}
class Repo(implicit ec: ExecutionContext) {
def getUser(id: Int): Future[Option[User]] = {
Future.successful(Some(User(id)))
}
def getRoom(id: Int): Future[Option[Room]] = {
Future.successful(Some(Room(id)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment