2016-11-26 11 views
0

Я использую play-json для сопоставления классов Jones с именами и перечислениями. Я ищу умный способ создания Formats неявно, так как мой проект содержит множество определений типов.Производить сериализатор классов классов и десериализатор неявно с помощью play-json


На данный момент я создал простую функцию для генерации Formats для Перечисления:

def formatEnum[E <: Enumeration](enum: E) = Format(Reads.enumNameReads(enum), Writes.enumNameWrites) 

Но он принимает без неявного аргумента, поэтому он не может быть использован в качестве неявного преобразователя.


Я попытался сделать то же самое для случая классов:

implicit def caseFormat[A] = Json.format[A] 

Но я получаю сообщение об ошибке «Нет исключить его или unapplySeq функции найдены», поскольку Json.format не макрос, который проверить структуру класса ,

Затем я попытался создать свой макрос таким образом:

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, хотя существует неявное четкости, который должен генерировать значение.


Конечно, я могу просто определить многие неявные значения val, но я думаю, что есть более умный способ сделать это.

+0

вы можете принять ответ, если это помогает? – phantomastray

ответ

0

Предполагая, что у вас много классов дел, и вы хотите, чтобы 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 
    } 
} 

Оптимальным вариантом было бы повторное использование устройства чтения/записи путем кэширования и поиска. Вы также можете узнать больше о play-json.

Вы можете использовать это как:

case class Entity(a: String, b: Int) 
val e = Entity("Stack", 0) 

e.toJson() 
+0

Он работает, спасибо за ваш ответ !! – WalkerTR

+0

рад, что это сработало. :) – phantomastray

+0

Не работает. Get 'scala.ScalaReflectionException: тип T не является классом – Vladislav

 Смежные вопросы

  • Нет связанных вопросов^_^