diff options
author | Mathias <mathias@decodified.com> | 2014-09-22 09:19:55 +0200 |
---|---|---|
committer | Mathias <mathias@decodified.com> | 2014-09-22 09:19:55 +0200 |
commit | dce0643476bd82a8a546900383a95fd72d1be243 (patch) | |
tree | 42b08c713fdf36238a3f2c7f791d2b26e475b1d7 | |
parent | a6aaf5164ae8b9dda62327c56349de9d97e7721c (diff) | |
parent | 12d83eb4b4b7c749cafe34f4a557c5ce153e4cdf (diff) | |
download | spray-json-dce0643476bd82a8a546900383a95fd72d1be243.tar.gz spray-json-dce0643476bd82a8a546900383a95fd72d1be243.tar.bz2 spray-json-dce0643476bd82a8a546900383a95fd72d1be243.zip |
Merge pull request #117 from chris-martin/jsonFormat0
Add jsonFormat0 for fieldless case classes
-rw-r--r-- | src/main/scala/spray/json/ProductFormats.scala | 9 | ||||
-rw-r--r-- | src/test/scala/spray/json/ProductFormatsSpec.scala | 19 |
2 files changed, 28 insertions, 0 deletions
diff --git a/src/main/scala/spray/json/ProductFormats.scala b/src/main/scala/spray/json/ProductFormats.scala index 971c7a6..5f5a9f4 100644 --- a/src/main/scala/spray/json/ProductFormats.scala +++ b/src/main/scala/spray/json/ProductFormats.scala @@ -26,6 +26,15 @@ import scala.util.control.NonFatal trait ProductFormats extends ProductFormatsInstances { this: StandardFormats => + def jsonFormat0[T](construct: () => T): RootJsonFormat[T] = + new RootJsonFormat[T] { + def write(p: T) = JsObject() + def read(value: JsValue) = value match { + case JsObject(_) => construct() + case _ => throw new DeserializationException("Object expected") + } + } + // helpers protected def productElement2Field[T](fieldName: String, p: Product, ix: Int, rest: List[JsField] = Nil) diff --git a/src/test/scala/spray/json/ProductFormatsSpec.scala b/src/test/scala/spray/json/ProductFormatsSpec.scala index 8e3390d..c4bb489 100644 --- a/src/test/scala/spray/json/ProductFormatsSpec.scala +++ b/src/test/scala/spray/json/ProductFormatsSpec.scala @@ -20,6 +20,7 @@ import org.specs2.mutable._ class ProductFormatsSpec extends Specification { + case class Test0() case class Test2(a: Int, b: Option[Double]) case class Test3[A, B](as: List[A], bs: List[B]) case class TestTransient(a: Int, b: Option[Double]) { @@ -30,6 +31,7 @@ class ProductFormatsSpec extends Specification { trait TestProtocol { this: DefaultJsonProtocol => + implicit val test0Format = jsonFormat0(Test0) implicit val test2Format = jsonFormat2(Test2) implicit def test3Format[A: JsonFormat, B: JsonFormat] = jsonFormat2(Test3.apply[A, B]) implicit def testTransientFormat = jsonFormat2(TestTransient) @@ -162,4 +164,21 @@ class ProductFormatsSpec extends Specification { } } + "A JsonFormat created with `jsonFormat`, for a case class with 0 elements," should { + import TestProtocol1._ + val obj = Test0() + val json = JsObject() + "convert to a respective JsObject" in { + obj.toJson mustEqual json + } + "convert a JsObject to the respective case class instance" in { + json.convertTo[Test0] mustEqual obj + } + "ignore additional members during deserialization" in { + JsObject("a" -> JsNumber(42)).convertTo[Test0] mustEqual obj + } + "throw a DeserializationException if the JsValue is not a JsObject" in ( + JsNull.convertTo[Test0] must throwA(new DeserializationException("Object expected")) + ) + } } |