Skip to content

Instantly share code, notes, and snippets.

@dacc
Created February 4, 2013 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacc/9840ae5a37d4b03c759a to your computer and use it in GitHub Desktop.
Save dacc/9840ae5a37d4b03c759a to your computer and use it in GitHub Desktop.
package exaptic.web.util
import scala.reflect.runtime.universe.{TypeTag, newTermName}
import net.liftweb.http.js.JE.{JsVar, JsObj, AnonFunc}
import net.liftweb.http.js.JsCmd
import net.liftweb.http.{JsContext, SHtml}
import net.liftweb.common.Full
import net.liftweb.json.JsonAST.JValue
import net.liftweb.json.DefaultFormats
import net.liftweb.http.js.JsCmds._
object ServerCall {
def apply[T <: (P1, P2) => JsCmd, P1, P2](f: T)(implicit tag: TypeTag[T], p1: Manifest[P1], p2: Manifest[P2]) = new ServerCall2(f, tag, p1, p2)
def apply[T <: (P1, P2, P3) => JsCmd, P1, P2, P3](f: T)(implicit tag: TypeTag[T], p1: Manifest[P1], p2: Manifest[P2], p3: Manifest[P3]) = new ServerCall3(f, tag, p1, p2, p3)
protected def getParamNames(tag: TypeTag[_]): List[String] = {
val method = tag.tpe.declaration(newTermName("apply")).asMethod
method.paramss(0).map(_.name.toString).toList
}
}
abstract class ServerCall(val tag: TypeTag[_], val paramManifests: Seq[Manifest[_]]) {
val paramNames = ServerCall.getParamNames(tag)
val funcParams = (paramNames :: "onSuccess" :: "onFailure" :: Nil).mkString(", ")
val paramObj = JsObj(paramNames.map(p => p -> JsVar(p)):_*)
def asFunc: AnonFunc = {
val context = new JsContext(Full("onSuccess()"), Full("console.log('ack')")) // TODO error param?
val func = (jvalue: JValue) => applyJValue(jvalue)
AnonFunc(funcParams, SHtml.jsonCall(paramObj, context, func))
}
// def asDummyFunc: AnonFunc = {
// AnonFunc(funcParams, )
// }
protected def extract[T](param: Manifest[T])(implicit params: JValue) = {
val paramIndex = paramManifests.indexOf(param)
(params \ paramNames(paramIndex)).extract(DefaultFormats, param)
}
protected def applyJValue(implicit params: JValue): JsCmd
}
class ServerCall2[T <: (P1, P2) => JsCmd, P1, P2](f: T, tag: TypeTag[T], p1: Manifest[P1], p2: Manifest[P2]) extends ServerCall(tag, Seq(p1, p2)) {
def applyJValue(implicit params: JValue) = f(extract(p1), extract(p2))
}
class ServerCall3[T <: (P1, P2, P3) => JsCmd, P1, P2, P3](f: T, tag: TypeTag[T], p1: Manifest[P1], p2: Manifest[P2], p3: Manifest[P3]) extends ServerCall(tag, Seq(p1, p2, p3)) {
def applyJValue(implicit params: JValue) = f(extract(p1), extract(p2), extract(p3))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment