diff options
author | Li Haoyi <haoyi.li@databricks.com> | 2019-09-14 19:22:48 +0800 |
---|---|---|
committer | Li Haoyi <haoyi.li@databricks.com> | 2019-09-14 19:22:48 +0800 |
commit | edd1f62ce364f8b559431249e2350c2bb75fccec (patch) | |
tree | 337f0528e9284759800228e46f649cbc01f5edfe /cask/src/cask/main | |
parent | 0460ad2eca7fcdec1ff29c289dad4ecc76dde9c6 (diff) | |
download | cask-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.scala | 60 | ||||
-rw-r--r-- | cask/src/cask/main/Main.scala | 4 | ||||
-rw-r--r-- | cask/src/cask/main/Routes.scala | 12 |
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 |