使用 play-json 隐式生成 case 类 序列化器和反序列化器
Generate case classes serializer and deserializer implicitly using play-json
我正在使用 play-json 将 Json 映射到大小写 classes 或枚举。我正在寻找一种隐式创建 Formats
的聪明方法,因为我的项目包含许多类型定义。
目前我创建了一个简单的函数来为枚举生成 Formats
:
def formatEnum[E <: Enumeration](enum: E) = Format(Reads.enumNameReads(enum), Writes.enumNameWrites)
但它需要一个非隐式参数,所以它不能用作隐式转换器。
我尝试对案例 classes:
做同样的事情
implicit def caseFormat[A] = Json.format[A]
但是我收到错误 "No unapply or unapplySeq function found",因为 Json.format
是一个检查 class.
结构的宏
然后我尝试以这种方式创建我的宏:
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
implicit def caseFormat[A](): Format[A] = macro impl[A]
def impl[A: c.WeakTypeTag](c: Context)(): c.Expr[Reads[A]] = {
import c.universe._
val TypeRef(pre, sym, args) = weakTypeTag[A].tpe
val t = args.head
val expr = q"Json.format[$t]"
c.Expr[Reads[A]](expr)
}
但是编译器没有找到隐式 Format
,虽然有一个隐式 def 应该生成值。
当然我可以简单地定义许多隐式 val,但我认为有更聪明的方法来做到这一点。
假设您有很多案例 类 并且您希望 json 即时将其序列化而无需编写剧本-json 编写器。
import play.api.libs.json._
import scala.reflect.runtime.{universe => ru}
implicit class writeutil[T: ru.TypeTag](i: T) {
implicit val writer = Json.writes[T]
def toJson() = Json.toJson(i)
}
def toInstance[T: ru.TypeTag](s: String): Option[T] = {
implicit val reader = Json.reads[T]
Json.fromJson[T](Json.parse(s)) match {
case JsSuccess(r: T, path: JsPath) => Option(r)
case e: JsError => None
}
}
最佳实施方式是通过缓存和查找重新使用 reader/writer。您还可以阅读有关 play-json.
的更多信息
您可以将其用作:
case class Entity(a: String, b: Int)
val e = Entity("Stack", 0)
e.toJson()
我正在使用 play-json 将 Json 映射到大小写 classes 或枚举。我正在寻找一种隐式创建 Formats
的聪明方法,因为我的项目包含许多类型定义。
目前我创建了一个简单的函数来为枚举生成 Formats
:
def formatEnum[E <: Enumeration](enum: E) = Format(Reads.enumNameReads(enum), Writes.enumNameWrites)
但它需要一个非隐式参数,所以它不能用作隐式转换器。
我尝试对案例 classes:
做同样的事情implicit def caseFormat[A] = Json.format[A]
但是我收到错误 "No unapply or unapplySeq function found",因为 Json.format
是一个检查 class.
然后我尝试以这种方式创建我的宏:
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
implicit def caseFormat[A](): Format[A] = macro impl[A]
def impl[A: c.WeakTypeTag](c: Context)(): c.Expr[Reads[A]] = {
import c.universe._
val TypeRef(pre, sym, args) = weakTypeTag[A].tpe
val t = args.head
val expr = q"Json.format[$t]"
c.Expr[Reads[A]](expr)
}
但是编译器没有找到隐式 Format
,虽然有一个隐式 def 应该生成值。
当然我可以简单地定义许多隐式 val,但我认为有更聪明的方法来做到这一点。
假设您有很多案例 类 并且您希望 json 即时将其序列化而无需编写剧本-json 编写器。
import play.api.libs.json._
import scala.reflect.runtime.{universe => ru}
implicit class writeutil[T: ru.TypeTag](i: T) {
implicit val writer = Json.writes[T]
def toJson() = Json.toJson(i)
}
def toInstance[T: ru.TypeTag](s: String): Option[T] = {
implicit val reader = Json.reads[T]
Json.fromJson[T](Json.parse(s)) match {
case JsSuccess(r: T, path: JsPath) => Option(r)
case e: JsError => None
}
}
最佳实施方式是通过缓存和查找重新使用 reader/writer。您还可以阅读有关 play-json.
的更多信息您可以将其用作:
case class Entity(a: String, b: Int)
val e = Entity("Stack", 0)
e.toJson()