package io.circe.generic.extras.encoding import io.circe.{ Encoder, Json, JsonObject } import io.circe.generic.extras.ConfigurableDeriver import scala.annotation.implicitNotFound import scala.language.experimental.macros /** * An encoder for a generic representation of a case class or ADT. * * Note that users typically will not work with instances of this class. */ @implicitNotFound( """Could not find ReprAsObjectEncoder for type ${A}. Some possible causes for this: - ${A} isn't a case class or sealed trat - some of ${A}'s members don't have codecs of their own - missing implicit Configuration""" ) trait ReprAsObjectEncoder[A] extends Encoder.AsObject[A] { def configuredEncodeObject(a: A)( transformMemberNames: String => String, transformDiscriminator: String => String, discriminator: Option[String] ): JsonObject final protected[this] def addDiscriminator[B]( encode: Encoder[B], value: B, name: String, discriminator: Option[String] ): JsonObject = discriminator match { case None => JsonObject.singleton(name, encode(value)) case Some(disc) => encode match { case oe: Encoder.AsObject[B] @unchecked => oe.encodeObject(value).add(disc, Json.fromString(name)) case _ => JsonObject.singleton(name, encode(value)) } } final def encodeObject(a: A): JsonObject = configuredEncodeObject(a)(Predef.identity, Predef.identity, None) } object ReprAsObjectEncoder { implicit def deriveReprAsObjectEncoder[R]: ReprAsObjectEncoder[R] = macro ConfigurableDeriver.deriveConfiguredEncoder[R] }