MoultingYaml從JSON轉換YAML到/是spray.json相象爲YAML,因此有着極大的好處。 > JSON -使用MoultingYaml
但是,它不適合轉換YAML <提供現成的支持。我認爲這樣做會很有用,至少作爲一個示例代碼使用例如spray.json認爲該項目與之密切相關。
如果有人提示/指針,以使這種simplish代碼,謝謝。如果沒有,我可能會在這裏發佈並在這裏發佈。
MoultingYaml從JSON轉換YAML到/是spray.json相象爲YAML,因此有着極大的好處。 > JSON -使用MoultingYaml
但是,它不適合轉換YAML <提供現成的支持。我認爲這樣做會很有用,至少作爲一個示例代碼使用例如spray.json認爲該項目與之密切相關。
如果有人提示/指針,以使這種simplish代碼,謝謝。如果沒有,我可能會在這裏發佈並在這裏發佈。
您可以將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] = [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
}
這是我想出了。
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")
}
}
}
我已經測試了這個。如果有人想看,請說。
謝謝@aleksey我有一個直接的AST到AST解決方案烹飪。一旦我得到測試並且通過,它會在這裏發佈。我需要支持「任何」JSON數據。 – akauppi