Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Last active August 29, 2015 14:09
Show Gist options
  • Save gakuzzzz/10b7eee52ba03396f34c to your computer and use it in GitHub Desktop.
Save gakuzzzz/10b7eee52ba03396f34c to your computer and use it in GitHub Desktop.
ActionBuilderZipper
import play.api.mvc._
import scala.concurrent.Future
case class ZippedRequest[A, R1[_] <: Request[_], R2[_] <: Request[_]](_1: R1[A], _2: R2[A]) extends WrappedRequest[A](_1.asInstanceOf[Request[A]])
object ActionBuilderZipper {
private def zip[R1[_] <: Request[_], R2[_] <: Request[_]](b1: ActionBuilder[R1], b2: ActionBuilder[R2]): ActionBuilder[({type L[A] = ZippedRequest[A, R1, R2]})#L] = {
new ActionBuilder[({type L[A] = ZippedRequest[A, R1, R2]})#L] {
override def invokeBlock[A](request: Request[A], block: (ZippedRequest[A, R1, R2]) => Future[Result]) = {
b1.invokeBlock(request, { r1: R1[A] =>
b2.invokeBlock(request, { r2: R2[A] =>
block(ZippedRequest[A, R1, R2](r1, r2))
})
})
}
}
}
implicit class _Zipper[R1[_] <: Request[_]](val b1: ActionBuilder[R1]) extends AnyVal {
def zip[R2[_] <: Request[_]](b2: ActionBuilder[R2]): ActionBuilder[({type L[A] = ZippedRequest[A, R1, R2]})#L] =
ActionBuilderZipper.zip(b1, b2)
}
}
case class FooRequest[A](request: Request[A]) extends WrappedRequest[A](request)
case class BarRequest[A](request: Request[A]) extends WrappedRequest[A](request)
case class BazRequest[A](request: Request[A]) extends WrappedRequest[A](request)
object FooAction extends ActionBuilder[FooRequest] {
override def invokeBlock[A](request: Request[A], block: (FooRequest[A]) => Future[Result]) = {
block(FooRequest(request))
}
}
object BarAction extends ActionBuilder[BarRequest] {
override def invokeBlock[A](request: Request[A], block: (BarRequest[A]) => Future[Result]) = {
block(BarRequest(request))
}
}
object BazAction extends ActionBuilder[BazRequest] {
override def invokeBlock[A](request: Request[A], block: (BazRequest[A]) => Future[Result]) = {
block(BazRequest(request))
}
}
object SampleController extends Controller {
import controllers.ActionBuilderZipper._
val MyCoolAction = FooAction zip BarAction zip BazAction
val ∧ = ZippedRequest
def index = MyCoolAction(parse.anyContent) { case foo ∧ bar ∧ baz =>
Ok(s"$foo, $bar, $baz")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment