All Downloads are FREE. Search and download functionalities are using the official Maven repository.

argonaut.EncodeJson.scala Maven / Gradle / Ivy

The newest version!
package argonaut

import Json._
import JsonIdentity._
import EncodeJsonNumber._

/**
 * Encode an arbitrary value as a JSON value.
 *
 * @author Tony Morris
 */
trait EncodeJson[A] {
  /**
   * Encode the given value. Alias for `encode`.
   */
  def apply(a: A): Json = encode(a)

  /**
   * Encode the given value.
   */
  def encode(a: A): Json

  /**
   * Contravariant functor.
   */
  def contramap[B](f: B => A): EncodeJson[B] = {
    EncodeJson(b => apply(f(b)))
  }

  /**
   * Transform the resulting Json instance.
   */
  def mapJson(f: Json => Json): EncodeJson[A] = {
    val original = this
    (a: A) => f(original(a))
  }

  /**
   * Split on this encoder and the given encoder.
   */
  def <&>[B](x: => EncodeJson[B]): EncodeJson[Either[A, B]] = {
    EncodeJson {
      case Left(a) => apply(a)
      case Right(b) => x(b)
    }
  }
}

object EncodeJson extends EncodeJsons with EncodeJsonMacro {
  def apply[A](f: A => Json): EncodeJson[A] =
    (a: A) => f(a)

  def of[A: EncodeJson]: EncodeJson[A] = implicitly[EncodeJson[A]]
}

trait EncodeJsons extends GeneratedEncodeJsons {
  /* TODO: Come back to this.
  def contrazip[A, B](e: EncodeJson[A \/ B]): (EncodeJson[A], EncodeJson[B]) =
    (EncodeJson(a => e(a.left)), EncodeJson(b => e(b.right)))
  */

  implicit val JsonEncodeJson: EncodeJson[Json] =
    EncodeJson(q => q)

  implicit val HCursorEncodeJson: EncodeJson[HCursor] =
    EncodeJson(q => q.focus)

  implicit val UnitEncodeJson: EncodeJson[Unit] =
    EncodeJson(_ => jEmptyObject)

  implicit def ListEncodeJson[A](implicit e: EncodeJson[A]): EncodeJson[List[A]] =
    EncodeJson(a => jArray(a.map(e(_))))

  implicit def VectorEncodeJson[A](implicit e: EncodeJson[List[A]]): EncodeJson[Vector[A]] =
    EncodeJson(a => e(a.toList))

  implicit def StreamEncodeJson[A](implicit e: EncodeJson[A]): EncodeJson[Stream[A]] =
    EncodeJson(a => jArray(a.toList.map(e(_))))

  implicit val StringEncodeJson: EncodeJson[String] =
    EncodeJson(jString)

  implicit val UUIDEncodeJson: EncodeJson[java.util.UUID] =
    StringEncodeJson.contramap(_.toString)

  implicit val DoubleEncodeJson: EncodeJson[Double] =
    EncodeJson(a => a.asPossibleJsonNumber.fold(jNull)(_.asJson))

  implicit val FloatEncodeJson: EncodeJson[Float] =
    EncodeJson(a => a.asPossibleJsonNumber.fold(jNull)(_.asJson))

  implicit val IntEncodeJson: EncodeJson[Int] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val LongEncodeJson: EncodeJson[Long] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val ShortEncodeJson: EncodeJson[Short] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val ByteEncodeJson: EncodeJson[Byte] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val BigDecimalEncodeJson: EncodeJson[BigDecimal] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val BigIntEncodeJson: EncodeJson[BigInt] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val BooleanEncodeJson: EncodeJson[Boolean] =
    EncodeJson(jBool)

  implicit val CharEncodeJson: EncodeJson[Char] =
    EncodeJson(a => jString(a.toString))

  implicit val JDoubleEncodeJson: EncodeJson[java.lang.Double] =
    EncodeJson(a => a.asPossibleJsonNumber.fold(jNull)(_.asJson))

  implicit val JFloatEncodeJson: EncodeJson[java.lang.Float] =
    EncodeJson(a => a.asPossibleJsonNumber.fold(jNull)(_.asJson))

  implicit val JIntegerEncodeJson: EncodeJson[java.lang.Integer] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val JLongEncodeJson: EncodeJson[java.lang.Long] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val JShortEncodeJson: EncodeJson[java.lang.Short] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val JByteEncodeJson: EncodeJson[java.lang.Byte] =
    EncodeJson(a => a.asJsonNumber.asJson)

  implicit val JBooleanEncodeJson: EncodeJson[java.lang.Boolean] =
    EncodeJson(a => jBool(a.booleanValue))

  implicit val JCharacterEncodeJson: EncodeJson[java.lang.Character] =
    EncodeJson(a => jString(a.toString))

  implicit def OptionEncodeJson[A](implicit e: EncodeJson[A]): EncodeJson[Option[A]] = {
    EncodeJson(_ match {
      case None    => jNull
      case Some(a) => e(a)
    })
  }

  implicit def EitherEncodeJson[A, B](implicit ea: EncodeJson[A], eb: EncodeJson[B]): EncodeJson[Either[A, B]] = {
    EncodeJson(_ match {
      case Left(a)  => jSingleObject("Left", ea(a))
      case Right(b) => jSingleObject("Right", eb(b))
    })
  }

  implicit def MapEncodeJson[K, V](implicit K: EncodeJsonKey[K], e: EncodeJson[V]): EncodeJson[Map[K, V]] = {
    EncodeJson(x => jObjectAssocList(
      x.toList.map{
        case (k, v) => (K.toJsonKey(k), e(v))
      }
    ))
  }

  implicit def SetEncodeJson[A](implicit e: EncodeJson[A]): EncodeJson[Set[A]] = {
    EncodeJson(ListEncodeJson[A].contramap((_: Set[A]).toList).apply(_))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy