Quasiquotes and Generics in Scala -


i'm using play framework , trying write action can parse protobuf request following:

def asyncprotoaction(block: protorequesta => future[result]): action[anycontent] = {     action.async { request =>         request.contenttype match {             case some("application/protobuf") => request.body.asraw match {                 case some(raw) => raw.asbytes(1024 * 1024) match {                     case some(rawbytes) =>                         val proto = protorequesta.parsefrom(rawbytes)                         block(proto)                     case _ => ...                 }             }         }     } } 

here, protorequesta generated object using scalapb. works, however, have lot of protobuf request objects. try rewrite using macro:

object actions {   def asyncprotoaction[t](block: t => future[result]):          action[anycontent] = macro asyncprotoaction_impl[t]    def asyncprotoaction_impl[t: c.weaktypetag](c: blackbox.context)        (block: c.tree) = { import c.universe._     val prototype = weaktypeof[t]     q"""import play.api.mvc._         action.async { request =>           request.contenttype match {             case some("application/protobuf") =>               request.body.asraw match {                 case some(raw) =>                   raw.asbytes(1024 * 1024) match {                     case some(rawbytes) =>                       val proto = $prototype.parsefrom(rawbytes)                       $block(proto)                     case _ => ...                   }               }           }         }"""   } } 

this doesn't work. compilation error value parsefrom not member of packagename.protorequesta.

i tried showraw(tq"$prototype") in repl, output string = typetree(). guess correct output should string = select(ident(termname("packagename")), typename("protorequesta")). should do?

you've identified problem, when interpolate protorequesta type different protorequesta companion object. 1 easy solution interpolate symbol of companion object, can type's symbol. here's simplified example:

import scala.language.experimental.macros import scala.reflect.macros.blackbox.context  def companionobjectbarimpl[a: c.weaktypetag](c: context): c.tree = {   import c.universe._   q"${ symbolof[a].companion }.bar" }  def companionobjectbar[a]: int = macro companionobjectbarimpl[a] 

this macro work on type companion object bar method returns int. example:

scala> class foo; object foo { def bar = 10 } defined class foo defined object foo  scala> companionobjectbar[foo] res0: int = 10 

you should able similar.


Comments

Popular posts from this blog

php - Wordpress website dashboard page or post editor content is not showing but front end data is showing properly -

How to get the ip address of VM and use it to configure SSH connection dynamically in Ansible -

javascript - Get parameter of GET request -