aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/DerivedFormats.scala
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2018-03-08 16:53:44 -0800
committerJakob Odersky <jakob@odersky.com>2018-03-28 10:34:31 -0700
commitc5fe23594f66225eb18bf4e67472cd80023eb448 (patch)
tree58fe8509b3990932134c18e09ed69ee83b779373 /src/main/scala/DerivedFormats.scala
parent2f3f9aa851080b6c79f3af14b3fdfeab56feffec (diff)
downloadspray-json-derivation-c5fe23594f66225eb18bf4e67472cd80023eb448.tar.gz
spray-json-derivation-c5fe23594f66225eb18bf4e67472cd80023eb448.tar.bz2
spray-json-derivation-c5fe23594f66225eb18bf4e67472cd80023eb448.zip
Refactor build to use sbt-crossproject
Diffstat (limited to 'src/main/scala/DerivedFormats.scala')
-rw-r--r--src/main/scala/DerivedFormats.scala108
1 files changed, 0 insertions, 108 deletions
diff --git a/src/main/scala/DerivedFormats.scala b/src/main/scala/DerivedFormats.scala
deleted file mode 100644
index d0cac38..0000000
--- a/src/main/scala/DerivedFormats.scala
+++ /dev/null
@@ -1,108 +0,0 @@
-package spray.json
-
-import magnolia._
-
-import scala.language.experimental.macros
-
-/** Mixin that enables derivation of JSON formats for any product
- * (case classes) or coproduct (sealed traits) types. */
-trait DerivedFormats { self: BasicFormats =>
- type Typeclass[T] = JsonFormat[T]
-
- def combine[T](ctx: CaseClass[JsonFormat, T]): JsonFormat[T] =
- new JsonFormat[T] {
- override def write(value: T): JsValue = {
- val fields: Seq[(String, JsValue)] = ctx.parameters.map { param =>
- param.label -> param.typeclass.write(param.dereference(value))
- }
- JsObject(fields: _*)
- }
-
- override def read(value: JsValue): T = value match {
- case obj: JsObject =>
- if (ctx.isObject) {
- ctx.rawConstruct(Seq.empty)
- } else {
- ctx.construct { param =>
- param.typeclass.read(obj.fields(param.label))
- }
- }
- case js =>
- deserializationError(
- s"Cannot read JSON '$js' as a ${ctx.typeName.full}")
- }
- }
-
- def dispatch[T](ctx: SealedTrait[JsonFormat, T]): JsonFormat[T] = {
- val typeFieldName = ctx.annotations
- .collectFirst {
- case g: gadt => g.typeFieldName
- }
- .getOrElse("type")
-
- new JsonFormat[T] {
- override def write(value: T): JsValue = ctx.dispatch(value) { sub =>
- sub.typeclass.write(sub.cast(value)) match {
- case obj: JsObject =>
- JsObject(
- (Map(typeFieldName -> JsString(sub.typeName.short)) ++
- obj.fields).toSeq: _*)
- case js => js
- }
- }
-
- override def read(js: JsValue): T = {
- val typeName: String = js match {
- case obj: JsObject if obj.fields.contains(typeFieldName) =>
- obj.fields(typeFieldName).convertTo[String]
- case JsString(str) =>
- str
- case _ =>
- deserializationError(
- s"Cannot deserialize JSON to ${ctx.typeName.full} " +
- "because serialized type cannot be determined.")
- }
-
- ctx.subtypes.find(_.typeName.short == typeName) match {
- case Some(tpe) => tpe.typeclass.read(js)
- case None =>
- deserializationError(
- s"Cannot deserialize JSON to ${ctx.typeName.full} " +
- s"because type '${typeName}' is unsupported.")
- }
- }
- }
- }
-
- def jsonFormat[T]: RootJsonFormat[T] =
- macro DerivedFormatMacros.derivedFormat[T]
-
-}
-object DerivedFormats extends DerivedFormats with DefaultJsonProtocol
-
-trait ImplicitDerivedFormats extends DerivedFormats { self: BasicFormats =>
- implicit def implicitJsonFormat[T]: RootJsonFormat[T] =
- macro DerivedFormatMacros.derivedFormat[T]
-}
-object ImplicitDerivedFormats
- extends ImplicitDerivedFormats
- with DefaultJsonProtocol
-
-object DerivedFormatMacros {
- import scala.reflect.macros.whitebox._
-
- /** Utility that converts a magnolia-generated JsonFormat to a RootJsonFormat. */
- def derivedFormat[T: c.WeakTypeTag](c: Context): c.Tree = {
- import c.universe._
- val tpe = weakTypeOf[T].typeSymbol.asType
- val sprayPkg = c.mirror.staticPackage("spray.json")
- val valName = TermName(c.freshName("format"))
- q"""{
- val $valName = ${Magnolia.gen[T](c)}
- new $sprayPkg.RootJsonFormat[$tpe] {
- def write(value: $tpe) = $valName.write(value)
- def read(value: $sprayPkg.JsValue) = $valName.read(value)
- }
- }"""
- }
-}