From da6a5cad7ef0fe723ac126f921f97c36962f42af Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Sun, 8 Apr 2018 20:30:44 -0700 Subject: Restructure build --- yamlesque-spray-json/src/main/scala/formats.scala | 40 ++++++++++++++++ .../src/test/scala/FormatTests.scala | 53 ++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 yamlesque-spray-json/src/main/scala/formats.scala create mode 100644 yamlesque-spray-json/src/test/scala/FormatTests.scala (limited to 'yamlesque-spray-json') 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), + ) + ) + } + } + } + +} -- cgit v1.2.3