From 44d81d07b248fd0bc6b114cb861e3d435f0bb38d Mon Sep 17 00:00:00 2001 From: "piotr.sliwa" Date: Thu, 11 Jan 2018 23:31:09 +0100 Subject: [PATCH] Add jsonReader and jsonWriter functions for constructing readers and writers for case classes --- .../ProductFormatsInstances.scala.template | 17 +++------ .../ProductReadersInstances.scala.template | 36 ++++++++++++++++++ .../ProductWritersInstances.scala.template | 38 +++++++++++++++++++ .../scala/spray/json/ProductFormats.scala | 2 +- .../spray/json/AdditionalFormatsSpec.scala | 2 +- 5 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 src/main/boilerplate/spray/json/ProductReadersInstances.scala.template create mode 100644 src/main/boilerplate/spray/json/ProductWritersInstances.scala.template diff --git a/src/main/boilerplate/spray/json/ProductFormatsInstances.scala.template b/src/main/boilerplate/spray/json/ProductFormatsInstances.scala.template index 3d29b582..5ca23c9a 100644 --- a/src/main/boilerplate/spray/json/ProductFormatsInstances.scala.template +++ b/src/main/boilerplate/spray/json/ProductFormatsInstances.scala.template @@ -24,18 +24,11 @@ trait ProductFormatsInstances { self: ProductFormats with StandardFormats => jsonFormat(construct, [#p1#]) } def jsonFormat[[#P1 :JF#], T <: Product](construct: ([#P1#]) => T, [#fieldName1: String#]): RootJsonFormat[T] = new RootJsonFormat[T]{ - def write(p: T) = { - val fields = new collection.mutable.ListBuffer[(String, JsValue)] - fields.sizeHint(1 * 2) - [#fields ++= productElement##2Field[P1](fieldName1, p, 0)# - ] - JsObject(fields: _*) - } - def read(value: JsValue) = { - [#val p1V = fromField[P1](value, fieldName1)# - ] - construct([#p1V#]) - } + val writer = jsonWriter(construct, [#fieldName1: String#]) + val reader = jsonReader(construct, [#fieldName1: String#]) + + def write(p: T) = writer.write(p) + def read(value: JsValue) = reader.read(value) }# diff --git a/src/main/boilerplate/spray/json/ProductReadersInstances.scala.template b/src/main/boilerplate/spray/json/ProductReadersInstances.scala.template new file mode 100644 index 00000000..8538216c --- /dev/null +++ b/src/main/boilerplate/spray/json/ProductReadersInstances.scala.template @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011,2012 Mathias Doenitz, Johannes Rudolph + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package spray.json + +trait ProductReadersInstances { self: ProductFormats with StandardFormats => +[# // Case classes with 1 parameters + + def jsonReader1[[#P1 :JsonReader#], T <: Product :ClassManifest](construct: ([#P1#]) => T): RootJsonReader[T] = { + val Array([#p1#]) = extractFieldNames(classManifest[T]) + jsonReader(construct, [#p1#]) + } + def jsonReader[[#P1 :JsonReader#], T <: Product](construct: ([#P1#]) => T, [#fieldName1: String#]): RootJsonReader[T] = new RootJsonReader[T]{ + def read(value: JsValue) = { + [#val p1V = fromField[P1](value, fieldName1)# + ] + construct([#p1V#]) + } + }# + + +] +} diff --git a/src/main/boilerplate/spray/json/ProductWritersInstances.scala.template b/src/main/boilerplate/spray/json/ProductWritersInstances.scala.template new file mode 100644 index 00000000..d78a71e8 --- /dev/null +++ b/src/main/boilerplate/spray/json/ProductWritersInstances.scala.template @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011,2012 Mathias Doenitz, Johannes Rudolph + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package spray.json + +trait ProductWritersInstances { self: ProductFormats with StandardFormats => +[# // Case classes with 1 parameters + + def jsonWriter1[[#P1 :JsonWriter#], T <: Product :ClassManifest](construct: ([#P1#]) => T): RootJsonWriter[T] = { + val Array([#p1#]) = extractFieldNames(classManifest[T]) + jsonWriter(construct, [#p1#]) + } + def jsonWriter[[#P1 :JsonWriter#], T <: Product](construct: ([#P1#]) => T, [#fieldName1: String#]): RootJsonWriter[T] = new RootJsonWriter[T]{ + def write(p: T) = { + val fields = new collection.mutable.ListBuffer[(String, JsValue)] + fields.sizeHint(1 * 2) + [#fields ++= productElement##2Field[P1](fieldName1, p, 0)# + ] + JsObject(fields: _*) + } + }# + + +] +} diff --git a/src/main/scala/spray/json/ProductFormats.scala b/src/main/scala/spray/json/ProductFormats.scala index 7d6c63e2..9a1de644 100644 --- a/src/main/scala/spray/json/ProductFormats.scala +++ b/src/main/scala/spray/json/ProductFormats.scala @@ -24,7 +24,7 @@ import scala.util.control.NonFatal * Provides the helpers for constructing custom JsonFormat implementations for types implementing the Product trait * (especially case classes) */ -trait ProductFormats extends ProductFormatsInstances { +trait ProductFormats extends ProductFormatsInstances with ProductWritersInstances with ProductReadersInstances { this: StandardFormats => def jsonFormat0[T](construct: () => T): RootJsonFormat[T] = diff --git a/src/test/scala/spray/json/AdditionalFormatsSpec.scala b/src/test/scala/spray/json/AdditionalFormatsSpec.scala index eafceb21..049d3d95 100644 --- a/src/test/scala/spray/json/AdditionalFormatsSpec.scala +++ b/src/test/scala/spray/json/AdditionalFormatsSpec.scala @@ -26,7 +26,7 @@ class AdditionalFormatsSpec extends Specification { implicit def containerReader[T :JsonFormat] = lift { new JsonReader[Container[T]] { def read(value: JsValue) = value match { - case JsObject(fields) if fields.contains("content") => Container(Some(jsonReader[T].read(fields("content")))) + case JsObject(fields) if fields.contains("content") => Container(Some(spray.json.jsonReader[T].read(fields("content")))) case _ => deserializationError("Unexpected format: " + value.toString) } }