1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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)}
}
}
}
|