Вы можете конвертировать YAML/JSON в промежуточный формат объекта scala. Нечто подобное:
scala> import net.jcazevedo.moultingyaml.DefaultYamlProtocol._
import net.jcazevedo.moultingyaml.DefaultYamlProtocol._
scala> import net.jcazevedo.moultingyaml._
import net.jcazevedo.moultingyaml._
scala> import spray.json.DefaultJsonProtocol._
import spray.json.DefaultJsonProtocol._
scala> import spray.json._
import spray.json._
scala> val jsonStr = "[1,2,3]"
jsonStr: String = [1,2,3]
scala> val jsonAst = jsonStr.parseJson
jsonAst: spray.json.JsValue = [1,2,3]
scala> val yamlAst = jsonAst.convertTo[List[Int]](spray.json.DefaultJsonProtocol.listFormat).toYaml(net.jcazevedo.moultingyaml.DefaultYamlProtocol.listFormat)
yamlAst: net.jcazevedo.moultingyaml.YamlValue = YamlArray(Vector(YamlNumber(1), YamlNumber(2), YamlNumber(3)))
scala> val yamlStr = yamlAst.prettyPrint
yamlStr: String =
"- 1
- 2
- 3
"
scala> val recoveredJsonAst = yamlAst.convertTo[List[Int]](net.jcazevedo.moultingyaml.DefaultYamlProtocol.listFormat).toJson(spray.json.DefaultJsonProtocol.listFormat)
recoveredJsonAst: spray.json.JsValue = [1,2,3]
scala> val recoveredJsonStr = recoveredJsonAst.prettyPrint
recoveredJsonStr: String = [1, 2, 3]
Здесь YAML AST преобразуется в объект домена List[Int]
, а затем JSON AST, и наоборот. Вы можете сделать прямое преобразование между АСТ, но тогда вам придется писать это самостоятельно - больше работы, но лучше.
Приятно, что библиотека YAML имитирует знакомый интерфейс библиотеки JSON, но дело с имплицитами усложняется. Кроме того, из-за этого сложнее решить такие методы, как convertTo
. Импорт, как listFormat
становятся неоднозначными и т.д.
Немного чище, когда есть меньше конфликтов:
scala> case class Test(v: Int)
defined class Test
scala> import net.jcazevedo.moultingyaml.DefaultYamlProtocol._
import net.jcazevedo.moultingyaml.DefaultYamlProtocol._
scala> import net.jcazevedo.moultingyaml._
import net.jcazevedo.moultingyaml._
scala> import spray.json.DefaultJsonProtocol._
import spray.json.DefaultJsonProtocol._
scala> import spray.json._
import spray.json._
scala> implicit val TestAsJson = jsonFormat1(Test)
TestAsJson: spray.json.RootJsonFormat[Test] = [email protected]
scala> implicit val TestAsYaml = yamlFormat1(Test)
TestAsYaml: net.jcazevedo.moultingyaml.YamlFormat[Test] = [email protected]
scala> val jsonStr = """{"v":1}"""
jsonStr: String = {"v":1}
scala> val jsonAst = jsonStr.parseJson
jsonAst: spray.json.JsValue = {"v":1}
scala> val yamlAst = jsonAst.convertTo[Test].toYaml
yamlAst: net.jcazevedo.moultingyaml.YamlValue = YamlObject(Map(YamlString(v) -> YamlNumber(1)))
scala> val yamlStr = yamlAst.prettyPrint
yamlStr: String =
"v: 1
"
scala> val recoveredJsonAst = yamlAst.convertTo[Test].toJson
recoveredJsonAst: spray.json.JsValue = {"v":1}
scala> val recoveredJsonStr = recoveredJsonAst.prettyPrint
recoveredJsonStr: String =
{
"v": 1
}
Спасибо @aleksey У меня есть непосредственное приготовление раствора AST-to-AST. Вывешивать его здесь, как только у меня будут тесты для этого, и они пройдут. Мне нужно поддерживать «любые» данные JSON. – akauppi