I am using Argonaut for JSON serialization in Scala. Invoking the casecodec
methods usually involves some boilerplate that I'd like to reduce.
// fabulous domain-driven case class
case class Person(
name: String,
birthdate: Long,
birthloc: String,
genome: List[Int],
mother: Option[Person],
father: Option[Person],
cokeAndNotPepsi: Boolean
)
// generate JSON codec for it
implicit val personCodec: argonaut.CodecJson[Person] =
argonaut.Argonaut.casecodec7(Person.apply, Person.unapply)(
"name", "birthdate", "birthloc", "genome", "mother", "father", "cokeAndNotPepsi"
)
Using ClassTag
s, I can construct a string that resembles the casecodec
invocation:
def makeCaseCodec[T](implicit tag: ClassTag[T]): String = {
val clazz = tag.runtimeClass
val name = clazz.toString.split("\\$")(1)
val arity = clazz.getDeclaredFields.length
val names = clazz.getDeclaredFields
.map(field => s""""${field.getName}"""").mkString(", ")
s"implicit val codec$name = argonaut.Argonaut.casecodec$arity($name.apply, $name.unapply)($names)"
}
So then makeCaseCodec[Person]
returns the string literal below:
res1> implicit val codecPerson = argonaut.Argonaut.casecodec7(Person.apply, Person.unapply)("name", "birthdate", "birthloc", "genome", "mother", "father", "cokeAndNotPepsi")
How can I execute this string-building-function, say in a macro, at compile-time?
Aucun commentaire:
Enregistrer un commentaire