Skip to content

Instantly share code, notes, and snippets.

@rossabaker
Forked from casualjim/gist:1204395
Created September 8, 2011 21:58
Show Gist options
  • Save rossabaker/1204883 to your computer and use it in GitHub Desktop.
Save rossabaker/1204883 to your computer and use it in GitHub Desktop.
trait HandlerArgs extends FiniteStateMachineActor {
def isInitial: Boolean
}
class Handler extends ((Request, HandlerArgs) => Response)
class Middleware extends (Handler => Handler)
object Server {
type ResponseWriter = Response => Result
val handler: Handler
object Executor {
@tailrec
def apply(handle: Handler, write: ResponseWriter, onError: ErrorHandler): Response = {
val res = handle(req, args)
if (!args.isInitial) onError(new YouCantDoThisRightHereNowException())
if (!res.isInstanceOf[EndResponse]) {
write(res)
apply(handle, socket)
} else {
res
}
}
}
def apply(req: Request, args: HandlerArgs) = {
(future { Executor((r, a) => handler(r, a), socket.send _) } onComplete (socket.send _) onException (throw _)).get
}
}
sealed trait Response {
type ContentType
def headers: Map[String, String]
def content: ContentType
def update(statusLine: String, headers: Map[String, String], content: ContentType): ResponsePrelude
}
sealed trait ResponsePrelude extends Response {
def statusLine: String
def update(statusLine: String, headers: Map[String, String], content: ContentType): ResponsePrelude
}
sealed trait ResponseCompletion { self: Response =>
}
sealed trait ResponsePart extends Response {
def update(headers: Map[String, String], content: ContentType): ResponsePart
}
case class BeginResponse[T : Manifest](statusLine: String, headers: Map[String, String], content: T) extends ResponsePrelude {
type ContentType = T
def update(statusLine: String = this.statusLine, headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude =
copy(statusLine, headers, content)
}
case class ResponseChunk[T : Manifest](headers: Map[String, String], content: T) {
type ContentType = T
def update(headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude =
copy(headers, content)
}
case class EndResponse[T: Manifest](headers: Map[String, String], content: T) extends ResponseCompletion {
type ContentType = T
def update(headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude =
copy(headers, content)
}
case class DefaultResponse[T: Manifest](statusLine: String, headers: Map[String, String], content: T) extends ResponsePrelude with ResponseCompletion {
type ContentType = T
def update(statusLine: String = this.statusLine, headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude =
copy(statusLine, headers, content)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment