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

io.finch.DecodeEntity.scala Maven / Gradle / Ivy

The newest version!
package io.finch

import shapeless._

import java.util.UUID

/** Decodes an HTTP entity (eg: header, query-string param) represented as UTF-8 `String` into an arbitrary type `A`.
  */
trait DecodeEntity[A] {
  def apply(s: String): Either[Throwable, A]
}

object DecodeEntity extends HighPriorityDecode {

  /** Returns a [[DecodeEntity]] instance for a given type.
    */
  @inline def apply[A](implicit d: DecodeEntity[A]): DecodeEntity[A] = d

  implicit val decodeString: DecodeEntity[String] = instance(s => Right(s))

}

trait HighPriorityDecode extends LowPriorityDecode {

  implicit val decodeInt: DecodeEntity[Int] = instance(s =>
    try Right(s.toInt)
    catch { case e: Throwable => Left(e) }
  )

  implicit val decodeLong: DecodeEntity[Long] = instance(s =>
    try Right(s.toLong)
    catch { case e: Throwable => Left(e) }
  )

  implicit val decodeFloat: DecodeEntity[Float] = instance(s =>
    try Right(s.toFloat)
    catch { case e: Throwable => Left(e) }
  )

  implicit val decodeDouble: DecodeEntity[Double] = instance(s =>
    try Right(s.toDouble)
    catch { case e: Throwable => Left(e) }
  )

  implicit val decodeBoolean: DecodeEntity[Boolean] = instance(s =>
    try Right(s.toBoolean)
    catch { case e: Throwable => Left(e) }
  )

  implicit val decodeUUID: DecodeEntity[UUID] = instance(s =>
    if (s.length != 36) Left(new IllegalArgumentException(s"Too long for UUID: ${s.length}"))
    else
      try Right(UUID.fromString(s))
      catch { case e: Throwable => Left(e) }
  )

}

trait LowPriorityDecode {

  /** Creates an [[DecodeEntity]] instance from a given function `String => Either[Throwable, A]`. */
  def instance[A](fn: String => Either[Throwable, A]): DecodeEntity[A] = fn(_)

  /** Creates a [[Decode]] from `Generic` for single value case classes. */
  implicit def decodeFromGeneric[A, H <: HList, E](implicit
      gen: Generic.Aux[A, H],
      ev: (E :: HNil) =:= H,
      de: DecodeEntity[E]
  ): DecodeEntity[A] = instance(de(_).map(b => gen.from(b :: HNil)))
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy