MoultingYaml对于YAML来说是一个类似于spray.json的东西,非常有益。
但是,它没有为转换YAML< - >提供现成的支持。 JSON。我认为这样有用,至少作为使用例如的示例代码。 spray.json认为该项目与之密切相关。
如果有人提示/制作如此简洁的代码,谢谢。如果没有,我可能会在这里发布并发布它。
答案 0 :(得分:1)
这就是我想出来的。
import spray.json._
import net.jcazevedo.{moultingyaml => my}
import net.jcazevedo.moultingyaml._
import net.jcazevedo.moultingyaml.DefaultYamlProtocol._
object JsonYamlProtocol extends my.CollectionFormats {
implicit object JsValueYamlFormat extends YamlFormat[JsValue] {
override
def write(jv: JsValue) = jv match {
case JsNumber(n) => YamlNumber(n)
case JsString(s) => YamlString(s)
case a: JsArray => seqFormat[JsValue].write( a.elements )
case o: JsObject => mapFormat[String,JsValue].write( o.fields )
case JsBoolean(b) => YamlBoolean(b)
case JsNull => YamlNull
case x => my.serializationError( s"Unexpected JSON value: $x" )
}
override
def read(yv: YamlValue): JsValue = yv match {
// tbd. probably can be simplified
case x: YamlNumber[_] => x.value match {
//case xx: Int => JsNumber(xx)
//case xx: Double => JsNumber(xx)
case xx: BigDecimal => JsNumber(xx)
}
case YamlString(s) => JsString(s)
case a: YamlArray => JsArray( vectorFormat[JsValue].read(a) )
case o: YamlObject => JsObject( mapFormat[String, JsValue].read(o) )
case YamlBoolean(b) => JsBoolean(b)
case YamlNull => JsNull
case x => my.deserializationError( s"Unexpected YAML value: $x" )
}
}
implicit object JsObjectYamlFormat extends YamlFormat[JsObject] {
override
def write(jso: JsObject): YamlValue = jso.fields.toYaml
override
def read(yv: YamlValue): JsObject = yv.convertTo[JsValue] match {
case jso: JsObject => jso
case x => my.deserializationError( s"Expected YAML object, got: $x" )
}
}
}
我已经对此进行了测试。如果有人想看,请说。
答案 1 :(得分:0)
您可以将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,反之亦然。你可以在AST之间进行直接转换,但是你必须自己编写 - 更多的工作,但更好的性能。
YAML库模仿熟悉的JSON库接口,但处理implicits变得更加复杂,这很好。此外,像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] = spray.json.ProductFormatsInstances$$anon$1@6b9fc143
scala> implicit val TestAsYaml = yamlFormat1(Test)
TestAsYaml: net.jcazevedo.moultingyaml.YamlFormat[Test] = net.jcazevedo.moultingyaml.ProductFormats$$anon$23@151806b4
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
}