Last active
March 10, 2016 04:01
-
-
Save simerplaha/430e28f28cc97effe864 to your computer and use it in GitHub Desktop.
Scala macro to generate a sealed trait's sub classes. This macro will generate a function (className: String, jsonString: String) => Option[A]. Depends on shapeless-argonaut.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.language.experimental.macros | |
import scala.reflect.macros.blackbox.Context | |
object JsonToClassNameMapper { | |
def generatePatternMatcher[A](): (String, String) => Option[A] = macro generatePatternMatcherImpl[A] | |
def generatePatternMatcherImpl[A: c.WeakTypeTag](c: Context)(): c.Tree = { | |
import c.universe._ | |
val subclasses: Set[c.universe.Symbol] = c.weakTypeOf[A].typeSymbol.asClass.knownDirectSubclasses | |
val cases = subclasses.map { | |
subClass => | |
val simpleName = subClass.fullName.substring(subClass.fullName.lastIndexOf(".") + 1, subClass.fullName.length) | |
cq"""$simpleName => jsonString.decodeOption[${subClass.asType}]""" | |
} | |
q"""(className: String, jsonString: String) => | |
className match { | |
case ..$cases | |
} | |
""" | |
} | |
} | |
////TEST//// | |
import argonaut._, Argonaut._, Shapeless._ | |
sealed trait Foobar | |
case class Foo(x: Int, fooString: String) extends Foobar | |
import JsonToClassNameMapper._ | |
object SealedExampleRunner extends App { | |
val myJson = """{"x": 1, "fooString" :"fooString", "lanaguge" : {}}""" | |
val foobarMapper = generatePatternMatcher[Foobar]() | |
val result = foobarMapper("Foo", myJson) | |
println("jsonToObject:" + result) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment