summaryrefslogtreecommitdiff
path: root/cask
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-07-28 20:35:51 +0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-07-28 21:03:15 +0800
commit229ab52fe36c0882bac8aa84ae484a12d339242a (patch)
treee9f8f5de1309cec044b6eb8c83f3fc5a86e5beda /cask
parent8b14cd206e008b4001f9b257f48870c8d40e8498 (diff)
downloadcask-229ab52fe36c0882bac8aa84ae484a12d339242a.tar.gz
cask-229ab52fe36c0882bac8aa84ae484a12d339242a.tar.bz2
cask-229ab52fe36c0882bac8aa84ae484a12d339242a.zip
wip more readme
Diffstat (limited to 'cask')
-rw-r--r--cask/src/cask/endpoints/FormEndpoint.scala4
-rw-r--r--cask/src/cask/endpoints/JsonEndpoint.scala2
-rw-r--r--cask/src/cask/endpoints/StaticEndpoints.scala4
-rw-r--r--cask/src/cask/endpoints/WebEndpoints.scala10
-rw-r--r--cask/src/cask/internal/Router.scala4
-rw-r--r--cask/src/cask/main/Decorators.scala11
-rw-r--r--cask/src/cask/main/Main.scala17
-rw-r--r--cask/src/cask/package.scala2
-rw-r--r--cask/test/src/test/cask/Decorated.scala11
-rw-r--r--cask/test/src/test/cask/FailureTests.scala15
-rw-r--r--cask/test/src/test/cask/FormJsonPost.scala1
11 files changed, 48 insertions, 33 deletions
diff --git a/cask/src/cask/endpoints/FormEndpoint.scala b/cask/src/cask/endpoints/FormEndpoint.scala
index 715c803..525dfde 100644
--- a/cask/src/cask/endpoints/FormEndpoint.scala
+++ b/cask/src/cask/endpoints/FormEndpoint.scala
@@ -56,13 +56,13 @@ class postForm(val path: String, override val subpath: Boolean = false) extends
"Unable to parse form data: " + e + "\n" + Util.stackTraceString(e)
))}
} yield {
- val formDataBindings =
+ cask.main.Decor(
formData
.iterator()
.asScala
.map(k => (k, formData.get(k).asScala.map(FormEntry.fromUndertow).toSeq))
.toMap
- formDataBindings
+ )
}
}
def wrapPathSegment(s: String): Input = Seq(FormValue(s, new io.undertow.util.HeaderMap))
diff --git a/cask/src/cask/endpoints/JsonEndpoint.scala b/cask/src/cask/endpoints/JsonEndpoint.scala
index 425f942..853e07d 100644
--- a/cask/src/cask/endpoints/JsonEndpoint.scala
+++ b/cask/src/cask/endpoints/JsonEndpoint.scala
@@ -43,7 +43,7 @@ class postJson(val path: String, override val subpath: Boolean = false) extends
obj <-
try Right(json.obj)
catch {case e: Throwable => Left(cask.model.Response("Input JSON must be a dictionary"))}
- } yield obj.toMap
+ } yield cask.main.Decor(obj.toMap)
}
def wrapPathSegment(s: String): Input = ujson.Js.Str(s)
}
diff --git a/cask/src/cask/endpoints/StaticEndpoints.scala b/cask/src/cask/endpoints/StaticEndpoints.scala
index 436fd25..7e1e6dd 100644
--- a/cask/src/cask/endpoints/StaticEndpoints.scala
+++ b/cask/src/cask/endpoints/StaticEndpoints.scala
@@ -14,6 +14,8 @@ class static(val path: String) extends Endpoint[String] {
Router.Result.Success(cask.model.Static(t + "/" + ctx.remaining.mkString("/")))
}
- def getRawParams(ctx: ParamContext) = Right(Map())
+ def getRawParams(ctx: ParamContext) = Right(
+ cask.main.Decor(Map())
+ )
def wrapPathSegment(s: String): Input = Seq(s)
}
diff --git a/cask/src/cask/endpoints/WebEndpoints.scala b/cask/src/cask/endpoints/WebEndpoints.scala
index d0ac46d..a5b2d02 100644
--- a/cask/src/cask/endpoints/WebEndpoints.scala
+++ b/cask/src/cask/endpoints/WebEndpoints.scala
@@ -11,10 +11,12 @@ trait WebEndpoint extends Endpoint[BaseResponse]{
type Input = Seq[String]
type InputParser[T] = QueryParamReader[T]
def getRawParams(ctx: ParamContext) = Right(
- ctx.exchange.getQueryParameters
- .asScala
- .map{case (k, vs) => (k, vs.asScala.toArray.toSeq)}
- .toMap
+ cask.main.Decor(
+ ctx.exchange.getQueryParameters
+ .asScala
+ .map{case (k, vs) => (k, vs.asScala.toArray.toSeq)}
+ .toMap
+ )
)
def wrapPathSegment(s: String) = Seq(s)
}
diff --git a/cask/src/cask/internal/Router.scala b/cask/src/cask/internal/Router.scala
index 4615bd3..c831240 100644
--- a/cask/src/cask/internal/Router.scala
+++ b/cask/src/cask/internal/Router.scala
@@ -217,10 +217,10 @@ class Router[C <: Context](val c: C) {
val argValuesSymbol = q"${c.fresh[TermName]("argValues")}"
val argSigsSymbol = q"${c.fresh[TermName]("argSigs")}"
val ctxSymbol = q"${c.fresh[TermName]("ctx")}"
- if (method.paramLists.length != argReaders.length) c.abort(
+ if (method.paramLists.length > argReaders.length) c.abort(
method.pos,
s"Endpoint ${method.name}'s number of parameter lists (${method.paramLists.length}) " +
- s"doesn't match number of decorators (${argReaders.length})"
+ s"cannot be more than the number of decorators (${argReaders.length})"
)
val argData = for(argListIndex <- method.paramLists.indices) yield{
val annotDeserializeType = annotDeserializeTypes(argListIndex)
diff --git a/cask/src/cask/main/Decorators.scala b/cask/src/cask/main/Decorators.scala
index 91cf92f..b262039 100644
--- a/cask/src/cask/main/Decorators.scala
+++ b/cask/src/cask/main/Decorators.scala
@@ -33,9 +33,18 @@ trait Endpoint[R] extends BaseDecorator{
trait BaseDecorator{
type Input
type InputParser[T] <: ArgReader[Input, T, ParamContext]
- def getRawParams(ctx: ParamContext): Either[cask.model.Response, Map[String, Input]]
+ def getRawParams(ctx: ParamContext): Either[cask.model.Response, Decor[Input]]
def getParamParser[T](implicit p: InputParser[T]) = p
+}
+object Decor{
+ def apply[Input](params: (String, Input)*) = new Decor(params.toMap, () => ())
+ def apply[Input](params: TraversableOnce[(String, Input)], cleanup: () => Unit = () => ()) = {
+ new Decor(params.toMap, cleanup)
+ }
+}
+class Decor[Input](val params: Map[String, Input], val cleanup: () => Unit){
+ def withCleanup(newCleanUp: () => Unit) = new Decor(params, newCleanUp)
}
trait Decorator extends BaseDecorator {
diff --git a/cask/src/cask/main/Main.scala b/cask/src/cask/main/Main.scala
index 9ac0022..fb07e77 100644
--- a/cask/src/cask/main/Main.scala
+++ b/cask/src/cask/main/Main.scala
@@ -57,18 +57,23 @@ abstract class BaseMain{
case None => writeResponse(exchange, handleError(404))
case Some(((routes, metadata), bindings, remaining)) =>
val params = for{
- endpointParams <- metadata.endpoint.getRawParams(ParamContext(exchange, remaining))
- decoratorParams <- Util.sequenceEither(
+ decoratorParams <- Util.sequenceEither[Response, cask.main.Decor[_], Seq](
metadata.decorators.map(e => e.getRawParams(ParamContext(exchange, remaining)))
)
- } yield (endpointParams ++ bindings.mapValues(metadata.endpoint.wrapPathSegment)) +: decoratorParams
+ endpointParams <- metadata.endpoint.getRawParams(ParamContext(exchange, remaining))
+ } yield (
+ (endpointParams.params ++ bindings.mapValues(metadata.endpoint.wrapPathSegment)) +:
+ decoratorParams.map(_.params),
+ () => {endpointParams.cleanup(); decoratorParams.foreach(_.cleanup())}
+ )
val result = params match{
case Left(resp) => resp
- case Right(paramValues) =>
- metadata.entryPoint
+ case Right((paramValues, cleanup)) =>
+ try metadata.entryPoint
.asInstanceOf[EntryPoint[cask.main.Routes, cask.model.ParamContext]]
.invoke(routes, ParamContext(exchange, remaining), paramValues)
+ finally cleanup()
}
@@ -86,8 +91,6 @@ abstract class BaseMain{
statusCode = 500)
)
}
-
-
}
}
}
diff --git a/cask/src/cask/package.scala b/cask/src/cask/package.scala
index 24a0a20..b7f1478 100644
--- a/cask/src/cask/package.scala
+++ b/cask/src/cask/package.scala
@@ -36,5 +36,7 @@ package object cask {
type Decorator = main.Decorator
type Endpoint[R] = main.Endpoint[R]
type BaseDecorator = main.BaseDecorator
+ type Decor[T] = main.Decor[T]
+ val Decor = main.Decor
}
diff --git a/cask/test/src/test/cask/Decorated.scala b/cask/test/src/test/cask/Decorated.scala
index ed377cf..3925bf1 100644
--- a/cask/test/src/test/cask/Decorated.scala
+++ b/cask/test/src/test/cask/Decorated.scala
@@ -7,10 +7,10 @@ object Decorated extends cask.MainRoutes{
override def toString = "[haoyi]"
}
class loggedIn extends cask.Decorator {
- def getRawParams(ctx: ParamContext) = Right(Map("user" -> new User()))
+ def getRawParams(ctx: ParamContext) = Right(cask.Decor("user" -> new User()))
}
class withExtra extends cask.Decorator {
- def getRawParams(ctx: ParamContext) = Right(Map("extra" -> 31337))
+ def getRawParams(ctx: ParamContext) = Right(cask.Decor("extra" -> 31337))
}
@withExtra()
@@ -32,5 +32,12 @@ object Decorated extends cask.MainRoutes{
world + user + extra
}
+ @withExtra()
+ @loggedIn()
+ @cask.get("/ignore-extra/:world")
+ def ignoreExtra(world: String)(user: User) = {
+ world + user
+ }
+
initialize()
}
diff --git a/cask/test/src/test/cask/FailureTests.scala b/cask/test/src/test/cask/FailureTests.scala
index dd6914a..3ed4249 100644
--- a/cask/test/src/test/cask/FailureTests.scala
+++ b/cask/test/src/test/cask/FailureTests.scala
@@ -5,7 +5,7 @@ import utest._
object FailureTests extends TestSuite {
class myDecorator extends cask.Decorator {
- def getRawParams(ctx: ParamContext) = Right(Map("extra" -> 31337))
+ def getRawParams(ctx: ParamContext) = Right(cask.Decor("extra" -> 31337))
}
val tests = Tests{
@@ -17,17 +17,7 @@ object FailureTests extends TestSuite {
initialize()
}
""").msg ==>
- "Endpoint hello's number of parameter lists (2) doesn't match number of decorators (1)"
-
- utest.compileError("""
- object Decorated extends cask.MainRoutes{
- @myDecorator()
- @cask.get("/hello/:world")
- def hello(world: String)= world
- initialize()
- }
- """).msg ==>
- "Endpoint hello's number of parameter lists (1) doesn't match number of decorators (2)"
+ "Endpoint hello's number of parameter lists (2) cannot be more than the number of decorators (1)"
utest.compileError("""
object Decorated extends cask.MainRoutes{
@@ -51,3 +41,4 @@ object FailureTests extends TestSuite {
}
}
}
+
diff --git a/cask/test/src/test/cask/FormJsonPost.scala b/cask/test/src/test/cask/FormJsonPost.scala
index 9db3d24..05a8761 100644
--- a/cask/test/src/test/cask/FormJsonPost.scala
+++ b/cask/test/src/test/cask/FormJsonPost.scala
@@ -18,4 +18,3 @@ object FormJsonPost extends cask.MainRoutes{
initialize()
}
-