Воспроизведение сериализации/десериализации Json взаимной рекурсии

Как сериализовать и десериализовать эти структуры с помощью комбинаторов Play Json?

final case class WriteGroupEntity(label: String, items: Map[String, WriteEntity])
final case class WriteEntity(label: String,
                             propertyType: String,
                             groups: Option[Map[String, WriteGroupEntity]])

person kapranov.anton    schedule 20.03.2019    source источник
comment
См. stackoverflow.com/a/35017126/7803797.   -  person Chaitanya Waikar    schedule 20.03.2019
comment
@ChaitanyaWaikar, я не нашел этого. Ему 3 года, поэтому рецепта нет :(   -  person kapranov.anton    schedule 20.03.2019
comment
Что уже пробовали на себе раньше?   -  person cchantep    schedule 20.03.2019
comment
@cchantep, я мог только вручную написать ser/deser   -  person kapranov.anton    schedule 20.03.2019


Ответы (1)


Прошло два дня, и я наконец нашел решение.

import play.api.libs.json._
import play.api.libs.functional.syntax._

final case class GroupEntity(label: String, items: Map[String, Entity])
final case class Entity(label: String,
                        propertyType: String,
                        groups: Option[Map[String, GroupEntity]])

implicit lazy val ge: OWrites[GroupEntity] = (
  (JsPath \ "label").write[String] and
    (JsPath \ "items").lazyWrite(Writes.map[Entity](e))
)(unlift(GroupEntity.unapply))

implicit val e: OWrites[Entity] = Json.writes[Entity]

implicit lazy val ger: Reads[GroupEntity] = (
  (JsPath \ "label").read[String] and
    (JsPath \ "items").lazyRead(Reads.map[Entity](er))
)(GroupEntity)

implicit val er = Json.reads[Entity]
person kapranov.anton    schedule 20.03.2019
comment
Это хорошо, но я в разработке, это небезопасно. Вы не можете отследить ошибку, пока Reading или Writing. - person Rex; 20.03.2019
comment
просто предложение, вам нужно создать свой собственный reads and writes для более безопасной проверки. - person Rex; 20.03.2019