summaryrefslogtreecommitdiff
path: root/cask/src/cask/main
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.li@databricks.com>2019-09-14 19:22:48 +0800
committerLi Haoyi <haoyi.li@databricks.com>2019-09-14 19:22:48 +0800
commitedd1f62ce364f8b559431249e2350c2bb75fccec (patch)
tree337f0528e9284759800228e46f649cbc01f5edfe /cask/src/cask/main
parent0460ad2eca7fcdec1ff29c289dad4ecc76dde9c6 (diff)
downloadcask-edd1f62ce364f8b559431249e2350c2bb75fccec.tar.gz
cask-edd1f62ce364f8b559431249e2350c2bb75fccec.tar.bz2
cask-edd1f62ce364f8b559431249e2350c2bb75fccec.zip
Rename `BaseDecorator` -> `Decorator`, `Decorator` -> `RawDecorator`, `BaseEndpoint` -> `Endpoint`, `Endpoint` -> `HttpEndpoint`
Diffstat (limited to 'cask/src/cask/main')
-rw-r--r--cask/src/cask/main/Decorators.scala60
-rw-r--r--cask/src/cask/main/Main.scala4
-rw-r--r--cask/src/cask/main/Routes.scala12
3 files changed, 39 insertions, 37 deletions
diff --git a/cask/src/cask/main/Decorators.scala b/cask/src/cask/main/Decorators.scala
index dd445a4..573c139 100644
--- a/cask/src/cask/main/Decorators.scala
+++ b/cask/src/cask/main/Decorators.scala
@@ -4,20 +4,41 @@ import cask.internal.{Conversion, Router}
import cask.internal.Router.ArgReader
import cask.model.{Request, Response}
+/**
+ * A [[Decorator]] allows you to annotate a function to wrap it, via
+ * `wrapFunction`. You can use this to perform additional validation before or
+ * after the function runs, provide an additional parameter list of params,
+ * open/commit/rollback database transactions before/after the function runs,
+ * or even retrying the wrapped function if it fails.
+ *
+ * Calls to the wrapped function are done on the `delegate` parameter passed
+ * to `wrapFunction`, which takes a `Map` representing any additional argument
+ * lists (if any).
+ */
+trait Decorator[InnerReturned, Input]{
+ final type InputTypeAlias = Input
+ type InputParser[T] <: ArgReader[Input, T, Request]
+ final type Delegate = Map[String, Input] => Router.Result[InnerReturned]
+ type OuterReturned <: Router.Result[Any]
+ def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned
+ def getParamParser[T](implicit p: InputParser[T]) = p
+}
/**
- * Annotates a Cask endpoint that returns a HTTP [[Response]]; similar to a
- * [[Decorator]] but with additional metadata and capabilities.
+ * A [[RawDecorator]] is a decorator that operates on the raw request and
+ * response stream, before and after the primary [[Endpoint]] does it's job.
*/
-trait Endpoint[InnerReturned, Input] extends BaseEndpoint[InnerReturned, Input] {
+trait RawDecorator extends Decorator[Response.Raw, Any]{
type OuterReturned = Router.Result[Response.Raw]
+ type InputParser[T] = NoOpParser[Any, T]
}
+
/**
- * An [[Endpoint]] that may return something else than a HTTP response, e.g.
+ * An [[HttpEndpoint]] that may return something else than a HTTP response, e.g.
* a websocket endpoint which may instead return a websocket event handler
*/
-trait BaseEndpoint[InnerReturned, Input] extends BaseDecorator[InnerReturned, Input]{
+trait Endpoint[InnerReturned, Input] extends Decorator[InnerReturned, Input]{
/**
* What is the path that this particular endpoint matches?
*/
@@ -42,7 +63,7 @@ trait BaseEndpoint[InnerReturned, Input] extends BaseDecorator[InnerReturned, In
}
/**
- * [[Endpoint]]s are unique among decorators in that they alone can bind
+ * [[HttpEndpoint]]s are unique among decorators in that they alone can bind
* path segments to parameters, e.g. binding `/hello/:world` to `(world: Int)`.
* In order to do so, we need to box up the path segment strings into an
* [[Input]] so they can later be parsed by [[getParamParser]] into an
@@ -53,33 +74,14 @@ trait BaseEndpoint[InnerReturned, Input] extends BaseDecorator[InnerReturned, In
}
/**
- * A [[Decorator]] that may deal with values other than HTTP [[Response]]s
- */
-trait BaseDecorator[InnerReturned, Input]{
- final type InputTypeAlias = Input
- type InputParser[T] <: ArgReader[Input, T, Request]
- final type Delegate = Map[String, Input] => Router.Result[InnerReturned]
- type OuterReturned <: Router.Result[Any]
- def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned
- def getParamParser[T](implicit p: InputParser[T]) = p
-}
-
-/**
- * A decorator allows you to annotate a function to wrap it, via
- * `wrapFunction`. You can use this to perform additional validation before or
- * after the function runs, provide an additional parameter list of params,
- * open/commit/rollback database transactions before/after the function runs,
- * or even retrying the wrapped function if it fails.
- *
- * Calls to the wrapped function are done on the `delegate` parameter passed
- * to `wrapFunction`, which takes a `Map` representing any additional argument
- * lists (if any).
+ * Annotates a Cask endpoint that returns a HTTP [[Response]]; similar to a
+ * [[RawDecorator]] but with additional metadata and capabilities.
*/
-trait Decorator extends BaseDecorator[Response.Raw, Any]{
+trait HttpEndpoint[InnerReturned, Input] extends Endpoint[InnerReturned, Input] {
type OuterReturned = Router.Result[Response.Raw]
- type InputParser[T] = NoOpParser[Any, T]
}
+
class NoOpParser[Input, T] extends ArgReader[Input, T, Request] {
def arity = 1
diff --git a/cask/src/cask/main/Main.scala b/cask/src/cask/main/Main.scala
index 1eb2dbc..32e6517 100644
--- a/cask/src/cask/main/Main.scala
+++ b/cask/src/cask/main/Main.scala
@@ -28,7 +28,7 @@ class Main(servers0: Routes*) extends BaseMain{
def allRoutes = servers0.toSeq
}
abstract class BaseMain{
- def mainDecorators = Seq.empty[cask.main.Decorator]
+ def mainDecorators = Seq.empty[cask.main.RawDecorator]
def allRoutes: Seq[Routes]
def port: Int = 8080
def host: String = "localhost"
@@ -88,7 +88,7 @@ abstract class BaseMain{
case None => writeResponse(exchange, handleNotFound())
case Some(((routes, metadata), routeBindings, remaining)) =>
val ctx = Request(exchange, remaining)
- def rec(remaining: List[Decorator],
+ def rec(remaining: List[RawDecorator],
bindings: List[Map[String, Any]]): Router.Result[Any] = try {
remaining match {
case head :: rest =>
diff --git a/cask/src/cask/main/Routes.scala b/cask/src/cask/main/Routes.scala
index ea9d6fe..f133fdb 100644
--- a/cask/src/cask/main/Routes.scala
+++ b/cask/src/cask/main/Routes.scala
@@ -7,8 +7,8 @@ import scala.reflect.macros.blackbox.Context
import language.experimental.macros
object Routes{
- case class EndpointMetadata[T](decorators: Seq[Decorator],
- endpoint: BaseEndpoint[_, _],
+ case class EndpointMetadata[T](decorators: Seq[RawDecorator],
+ endpoint: Endpoint[_, _],
entryPoint: EntryPoint[T, _])
case class RoutesEndpointsMetadata[T](value: EndpointMetadata[T]*)
object RoutesEndpointsMetadata{
@@ -19,15 +19,15 @@ object Routes{
val routeParts = for{
m <- c.weakTypeOf[T].members
- val annotations = m.annotations.filter(_.tree.tpe <:< c.weakTypeOf[BaseDecorator[_, _]]).reverse
+ val annotations = m.annotations.filter(_.tree.tpe <:< c.weakTypeOf[Decorator[_, _]]).reverse
if annotations.nonEmpty
} yield {
- if(!(annotations.head.tree.tpe <:< weakTypeOf[BaseEndpoint[_, _]])) c.abort(
+ if(!(annotations.head.tree.tpe <:< weakTypeOf[Endpoint[_, _]])) c.abort(
annotations.head.tree.pos,
s"Last annotation applied to a function must be an instance of Endpoint, " +
s"not ${annotations.head.tree.tpe}"
)
- val allEndpoints = annotations.filter(_.tree.tpe <:< weakTypeOf[BaseEndpoint[_, _]])
+ val allEndpoints = annotations.filter(_.tree.tpe <:< weakTypeOf[Endpoint[_, _]])
if(allEndpoints.length > 1) c.abort(
annotations.head.tree.pos,
s"You can only apply one Endpoint annotation to a function, not " +
@@ -70,7 +70,7 @@ object Routes{
trait Routes{
- def decorators = Seq.empty[cask.main.Decorator]
+ def decorators = Seq.empty[cask.main.RawDecorator]
private[this] var metadata0: Routes.RoutesEndpointsMetadata[this.type] = null
def caskMetadata =
if (metadata0 != null) metadata0