aboutsummaryrefslogtreecommitdiff
path: root/yamlesque-spray-json
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2018-04-08 20:30:44 -0700
committerJakob Odersky <jakob@odersky.com>2018-04-08 20:32:20 -0700
commitda6a5cad7ef0fe723ac126f921f97c36962f42af (patch)
treed86aae792a7c96c22685ba1657abc766d56d4be0 /yamlesque-spray-json
parent98f1acf269312545192be115c75a6cce58c00766 (diff)
downloadyamlesque-da6a5cad7ef0fe723ac126f921f97c36962f42af.tar.gz
yamlesque-da6a5cad7ef0fe723ac126f921f97c36962f42af.tar.bz2
yamlesque-da6a5cad7ef0fe723ac126f921f97c36962f42af.zip
Restructure build
Diffstat (limited to 'yamlesque-spray-json')
-rw-r--r--yamlesque-spray-json/src/main/scala/formats.scala40
-rw-r--r--yamlesque-spray-json/src/test/scala/FormatTests.scala53
2 files changed, 93 insertions, 0 deletions
diff --git a/yamlesque-spray-json/src/main/scala/formats.scala b/yamlesque-spray-json/src/main/scala/formats.scala
new file mode 100644
index 0000000..188f4a9
--- /dev/null
+++ b/yamlesque-spray-json/src/main/scala/formats.scala
@@ -0,0 +1,40 @@
+package yamlesque
+
+import spray.json._
+
+trait JsonYamlFormats {
+
+ implicit def jsonToYamlReader[A](implicit jsReader: JsonReader[A]): YamlReader[A] = new YamlReader[A] {
+ override def read(yaml: YamlValue): A = jsReader.read(JsonFormats.yamlToJson(yaml))
+ }
+
+ implicit def jsonToYamlWriter[A](implicit jsWriter: JsonWriter[A]): YamlWriter[A] = new YamlWriter[A] {
+ override def write(a: A): YamlValue = JsonFormats.jsonToYaml(jsWriter.write(a))
+ }
+
+}
+
+object JsonFormats {
+
+ def jsonToYaml(js: JsValue): YamlValue = js match {
+ case JsNull => YamlEmpty
+ case JsNumber(number) => YamlScalar(number.toString)
+ case JsBoolean(value) => YamlScalar(value.toString)
+ case JsString(value) => YamlScalar(value)
+ case JsArray(elements) => YamlSequence(elements.map(jsonToYaml _ ))
+ case JsObject(fields) => YamlMapping(fields.mapValues(jsonToYaml _ ))
+ }
+
+ val JsNumberPattern = """([-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)""".r
+
+ def yamlToJson(yaml: YamlValue): JsValue = yaml match {
+ case YamlEmpty => JsNull
+ case YamlScalar("true") => JsTrue
+ case YamlScalar("false") => JsFalse
+ case YamlScalar(JsNumberPattern(x)) => JsNumber(x.toDouble)
+ case YamlScalar(x) => JsString(x)
+ case YamlSequence(elements) => JsArray(elements.map(yamlToJson))
+ case YamlMapping(fields) => JsObject(fields.mapValues(yamlToJson))
+ }
+
+}
diff --git a/yamlesque-spray-json/src/test/scala/FormatTests.scala b/yamlesque-spray-json/src/test/scala/FormatTests.scala
new file mode 100644
index 0000000..93d763a
--- /dev/null
+++ b/yamlesque-spray-json/src/test/scala/FormatTests.scala
@@ -0,0 +1,53 @@
+package yamlesque
+
+import spray.json._
+import utest._
+
+object FormatTests extends TestSuite {
+
+ case class A(a1: Int, a2: Seq[B])
+ case class B(a: String, b: Option[Boolean])
+
+ object Protocol extends DefaultJsonProtocol with JsonYamlFormats {
+ implicit def bFormat = jsonFormat2(B)
+ implicit def aFormat = jsonFormat2(A)
+ }
+ import Protocol._
+
+ val tests = Tests {
+ "parse" - {
+ val str =
+ s"""|a1: 42
+ |a2:
+ | - a: hello world
+ | b: true
+ | - a: yoyo
+ |""".stripMargin
+
+ "parse yaml" - {
+ str.parseYaml ==> YamlMapping(
+ "a1" -> YamlScalar("42"),
+ "a2" -> YamlSequence(
+ YamlMapping(
+ "a" -> YamlScalar("hello world"),
+ "b" -> YamlScalar("true")
+ ),
+ YamlMapping(
+ "a" -> YamlScalar("yoyo")
+ )
+ )
+ )
+ }
+ "parse with json readers" - {
+ str.parseYaml.convertTo[A] ==> A(
+ 42,
+ Seq(
+ B("hello world", Some(true)),
+ B("yoyo", None),
+ )
+ )
+ }
+ }
+ }
+
+}