Skip to content

Commit

Permalink
Typing a Rest Action
Browse files Browse the repository at this point in the history
  • Loading branch information
nkpart committed Jan 21, 2010
1 parent 5c86fbe commit 5085839
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 13 deletions.
32 changes: 23 additions & 9 deletions src/main/scala/rest/rest.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import rest.Resourced
import scalaz._
import Scalaz._

package object rest {
implicit def showMe[T](t: T)(implicit r: Resourced[T]) = new {
Expand All @@ -8,22 +10,34 @@ package object rest {
def edit = r.edit(t)
}
}

implicit val restFunctor = new Functor[rest.Action] {
def fmap[A,B](a: Action[A], f: A => B): Action[B] = a match {
case Index => Index
case Create => Create
case Show(v) => Show(f(v))
case Update(v) => Update(f(v))
case Destroy(v) => Destroy(f(v))
case New => New
case Edit(v) => Edit(f(v))
}
}
}

package rest {

sealed trait Action
sealed trait Action[+T]

// Ze actions.
case object Index extends Action
case object Create extends Action
case class Show(id: String) extends Action
case class Update(id: String) extends Action
case class Destroy(id: String) extends Action
case object Index extends Action[Nothing]
case object Create extends Action[Nothing]
case class Show[T](id: T) extends Action[T]
case class Update[T](id: T) extends Action[T]
case class Destroy[T](id: T) extends Action[T]

// Ze actions for form requests
case object New extends Action
case class Edit(id: String) extends Action
case object New extends Action[Nothing]
case class Edit[T](id: T) extends Action[T]

// Represents resource root, and action
// eg. Base("breweries", Index) could represent GET /breweries
Expand All @@ -34,7 +48,7 @@ case class Edit(id: String) extends Action
case class Context(resource: String, id: String)

// A full request: any number of parent contexts and a final action
case class RestRequest(contexts: List[Context], resource: String, base: Action, contentType: Option[String])
case class RestRequest[T](contexts: List[Context], resource: String, base: Action[T], contentType: Option[String])

case class Resource(name: String) {
def show(id: String) = "/" + name + "/" + id
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/scapps/RichRequest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait RichRequest[IN[_]] {

def update[T](t: T)(implicit postable: RequestUpdate[T], fl: FoldLeft[IN]) = postable.update(request)(t)

lazy val action: Option[(String, Action)] = {
lazy val action: Option[(String, Action[String])] = {
request match {
case MethodParts(GET, List(base)) => Some((base, rest.Index))
case MethodParts(GET, List(base, "new")) => Some((base, New))
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/wd/controllers/BeersController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import com.google.appengine.api.datastore.DatastoreService

class BeersController(val ds: DatastoreService)(implicit val request: Request[Stream]) extends Controller with ControllerHelpers {

def handle(v: Action) = v match {
def handle(v: Action[String]) = v match {
case New => Some {
val breweryId = request("breweryKey")
breweryId ∘ { id =>
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/wd/controllers/BreweriesController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class BreweriesController(val ds: DatastoreService)(implicit val request: Reques

def find(keyName: String) = Brewery.findById(keyName)(ds)

def handle(v: Action): Option[Response[Stream]] = v match {
def handle(v: Action[String]): Option[Response[Stream]] = v match {
case New => render(breweries.nnew) η

case rest.Show(keyName) => {
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/wd/controllers/Home.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final class WorthDrinkingServlet extends ServletApplicationServlet[Stream, Strea
userService.createLoginURL("/")
})(r)).kleisli[Option]

def resource(base: String, f: (Request[Stream] => Action => Option[Response[Stream]])) = ☆((r: Request[Stream]) => {
def resource(base: String, f: (Request[Stream] => Action[String] => Option[Response[Stream]])) = ☆((r: Request[Stream]) => {
r.action match {
case Some((b, action)) if b == base => f(r)(action)
case _ => none
Expand Down

0 comments on commit 5085839

Please sign in to comment.