summaryrefslogtreecommitdiff
path: root/cask/src/cask/router/EntryPoint.scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2019-09-16 08:58:31 +0800
committerLi Haoyi <haoyi.sg@gmail.com>2019-09-16 08:58:31 +0800
commit583893aff7e39e085dbf5bec27c9b0b24e5e8d2e (patch)
treeb2cf94c9bef2824159d8c9bd4f4867163a6ef36c /cask/src/cask/router/EntryPoint.scala
parent4851f249c8124ce725576f4f87f097f16e2f3843 (diff)
downloadcask-583893aff7e39e085dbf5bec27c9b0b24e5e8d2e.tar.gz
cask-583893aff7e39e085dbf5bec27c9b0b24e5e8d2e.tar.bz2
cask-583893aff7e39e085dbf5bec27c9b0b24e5e8d2e.zip
Break up `Router.scala` into a `router/` folder with multiple files
Diffstat (limited to 'cask/src/cask/router/EntryPoint.scala')
-rw-r--r--cask/src/cask/router/EntryPoint.scala51
1 files changed, 51 insertions, 0 deletions
diff --git a/cask/src/cask/router/EntryPoint.scala b/cask/src/cask/router/EntryPoint.scala
new file mode 100644
index 0000000..6fe44fc
--- /dev/null
+++ b/cask/src/cask/router/EntryPoint.scala
@@ -0,0 +1,51 @@
+package cask.router
+
+
+import scala.collection.mutable
+
+
+/**
+ * What is known about a single endpoint for our routes. It has a [[name]],
+ * [[argSignatures]] for each argument, and a macro-generated [[invoke0]]
+ * that performs all the necessary argument parsing and de-serialization.
+ *
+ * Realistically, you will probably spend most of your time calling [[invoke]]
+ * instead, which provides a nicer API to call it that mimmicks the API of
+ * calling a Scala method.
+ */
+case class EntryPoint[T, C](name: String,
+ argSignatures: Seq[Seq[ArgSig[_, T, _, C]]],
+ doc: Option[String],
+ invoke0: (T, C, Seq[Map[String, Any]], Seq[Seq[ArgSig[Any, _, _, C]]]) => Result[Any]){
+
+ val firstArgs = argSignatures.head
+ .map(x => x.name -> x)
+ .toMap[String, ArgSig[_, T, _, C]]
+
+ def invoke(target: T,
+ ctx: C,
+ paramLists: Seq[Map[String, Any]]): Result[Any] = {
+
+ val missing = mutable.Buffer.empty[ArgSig[_, T, _, C]]
+
+ val unknown = paramLists.head.keys.filter(!firstArgs.contains(_))
+
+ for(k <- firstArgs.keys) {
+ if (!paramLists.head.contains(k)) {
+ val as = firstArgs(k)
+ if (as.reads.arity != 0 && as.default.isEmpty) missing.append(as)
+ }
+ }
+
+ if (missing.nonEmpty || unknown.nonEmpty) Result.Error.MismatchedArguments(missing.toSeq, unknown.toSeq)
+ else {
+ try invoke0(
+ target,
+ ctx,
+ paramLists,
+ argSignatures.asInstanceOf[Seq[Seq[ArgSig[Any, _, _, C]]]]
+ )
+ catch{case e: Throwable => Result.Error.Exception(e)}
+ }
+ }
+}