From c5fe23594f66225eb18bf4e67472cd80023eb448 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Thu, 8 Mar 2018 16:53:44 -0800 Subject: Refactor build to use sbt-crossproject --- src/main/scala/DerivedFormats.scala | 108 ------------------------------------ 1 file changed, 108 deletions(-) delete mode 100644 src/main/scala/DerivedFormats.scala (limited to 'src/main/scala/DerivedFormats.scala') 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) - } - }""" - } -} -- cgit v1.2.3