2016-11-24 8 views
1

MoultingYamlは、YAMLのスプライト.jsonに似ており、非常に有益です。MoultingYamlを使用してYAMLをJSONに/から変換する

ただし、YAML < - > JSONを変換するための既製のサポートは提供していません。私は、少なくともそのようなサンプルコードとして有用であると思います。プロジェクトが密接に関連しているspray.json。

誰かがこのような単純なコードを作成するためのヒント/ポインタを持っている場合は、ありがとうございます。もしそうでなければ、私はおそらくそれを思いついてここに投稿するでしょう。

答えて

0

YAML/JSONを中間のスカラオブジェクト形式に変換できます。そのような何か:

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ライブラリインターフェイスを模倣していますが、暗黙のうちに対処する方がより複雑になるのはいいことです。さらに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                                 
}   
+0

ありがとう@aleksey私は直接ASTからASTソリューションを調理しています。私はそれのためのテストを持っていれば、ここにそれを掲示し、彼らは合格します。 JSONデータをサポートする必要があります。 – akauppi

0

は、これは私が思いついたものです。

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") 
    } 
    } 
} 

私にはこれに関するテストがあります。誰かが見たいと思ったら、言ってください。

+0

すべてがうまくいくならば、jar to mavenリポジトリを公開する必要があります。 –

+0

私は 'YamlNumber'の場合より良い方法を知りたいと思っています。 JSONとは多少異なります。 – akauppi

+1

「YamlNumber」変換について質問するPRを投稿しました:https://github.com/jcazevedo/moultingyaml/pull/20 – akauppi

関連する問題