Разбор рекурсивной черты playsafe json scala - PullRequest
0 голосов
/ 03 января 2019

Я использую play-json_2.11 и пытаюсь рекурсивно анализировать некоторые классы дел

sealed trait Tree

case class Node(value: Float, child: Seq[Tree]) extends Tree

case class Leaf(leaf: Float) extends Tree

Таким образом, в основном каждый узел содержит значение и список деревьев (который может быть узлом).или Лист).

Поэтому я определяю неявных читателей в сопутствующих объектах классов case.и один в объекте с именем Tree

object Node {
  implicit val reader = Json.reads[Node]
}

object Leaf {
  implicit val reader = Json.reads[Leaf]
}

object Tree {
  implicit val treeReads = 
    __.read[Node].map(x => x:Tree) orElse __.read[Leaf].map(x => x:Tree)
}

Поскольку парсеры ссылаются друг на друга, я не могу определить их и получить следующую ошибку:

ScalaFiddle.scala:9: error: No instance of play.api.libs.json.Reads is available for scala.Seq[ScalaFiddle.Tree] in the implicit scope (Hint: if declared in the same file, make sure it's declared before)
implicit val reader = Json.reads[Node]

Как я могу разобратьДерево в этом случае?(Мне не нужно, чтобы это была особая черта)

Вот скрипка, которую я пробовал https://scalafiddle.io/sf/sX8OkWI/3

Мой ввод - это json, подобный этому

{
    "value": 1.0,
    "child": {
        "leaf": 2.0
    }
}

И я хотел бы разобрать это, чтобы иметь

Node(1.0, Leaf(2.0))

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Вам не нужны последствия в сопутствующих объектах .. или объектах в этом отношении:

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

sealed trait Tree

case class Node(value: Double, child: Tree) extends Tree
case class Leaf(leaf: Double) extends Tree

val json: JsValue = Json.parse("""
{
    "value": 1.0,
    "child": {
      "leaf": 2.0
    }
}
""")

implicit val nReader = Json.reads[Node]
implicit val lReader = Json.reads[Leaf]
implicit lazy val treeReads: Reads[Tree] = 
    __.lazyRead(nReader).map(x => x:Tree) orElse __.lazyRead(lReader).map(x => x:Tree)

json.validate[Tree] match {
  case s: JsSuccess[Tree] => {
    val place: Tree = s.get
    println(place)
  }
  case e: JsError => {
    println(e)
  }
}

https://scalafiddle.io/sf/sX8OkWI/13

0 голосов
/ 03 января 2019

Это то, что вам нужно

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

sealed trait Tree


case class Node(value: Float, child: Tree) extends Tree
object Node {
  implicit lazy val reader = Json.reads[Node]
}

case class Leaf(leaf: Float) extends Tree
object Leaf {
  implicit lazy val reader = Json.reads[Leaf]
}

object Tree {
  implicit lazy val treeReads: Reads[Tree] = 
    __.lazyRead(Node.reader).map(x => x:Tree) orElse __.lazyRead(Leaf.reader).map(x => x:Tree)
}


val json: JsValue = Json.parse("""
{
    "value": 5.0,
    "child": {
      "leaf": 7
    }
}
""")


println(json)

json.validate[Tree] match {
  case s: JsSuccess[Tree] => {
    val place: Tree = s.get
    println(place)
  }
  case e: JsError => {
    println(e)
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...