![JAR search and dependency download from the Maven repository](/logo.png)
mess.Decoder.scala Maven / Gradle / Ivy
The newest version!
package mess
import export.imports
import mess.ast.MsgPack
import mess.internal.ScalaVersionSpecifics._
import scala.annotation.tailrec
import scala.collection.mutable
trait Decoder[A] extends Serializable { self =>
def apply(m: MsgPack): Decoder.Result[A]
final def map[B](f: A => B): Decoder[B] = new Decoder[B] {
def apply(m: MsgPack): Decoder.Result[B] =
self(m) match {
case Right(v) => Right(f(v))
case Left(e) => Left(e)
}
}
final def mapF[B](f: A => Decoder.Result[B]): Decoder[B] = new Decoder[B] {
def apply(m: MsgPack): Decoder.Result[B] =
self(m) match {
case Right(v) => f(v)
case Left(e) => Left(e)
}
}
final def flatMap[B](f: A => Decoder[B]): Decoder[B] = new Decoder[B] {
def apply(m: MsgPack): Decoder.Result[B] =
self(m) match {
case Right(v) => f(v).apply(m)
case Left(e) => Left(e)
}
}
}
object Decoder extends LowPriorityDecoder with TupleDecoder {
type Result[A] = Either[DecodingFailure, A]
@inline def apply[A](implicit A: Decoder[A]): Decoder[A] = A
def lift[A](a: A): Decoder[A] = new Decoder[A] {
def apply(_m: MsgPack): Result[A] = Right(a)
}
def liftF[A](a: Result[A]): Decoder[A] = new Decoder[A] {
def apply(_m: MsgPack): Result[A] = a
}
implicit val decodeBoolean: Decoder[Boolean] = new Decoder[Boolean] {
def apply(m: MsgPack): Result[Boolean] = m.asBoolean match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Boolean", m))
}
}
implicit val decodeBytes: Decoder[Array[Byte]] = new Decoder[Array[Byte]] {
def apply(m: MsgPack): Result[Array[Byte]] = m.asByteArray match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Array[Byte]", m))
}
}
implicit val decodeByte: Decoder[Byte] = new Decoder[Byte] {
def apply(m: MsgPack): Result[Byte] = m.asByte match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Byte", m))
}
}
implicit val decodeShort: Decoder[Short] = new Decoder[Short] {
def apply(m: MsgPack): Result[Short] = m.asShort match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Short", m))
}
}
implicit val decodeInt: Decoder[Int] = new Decoder[Int] {
def apply(m: MsgPack): Result[Int] = m.asInt match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Int", m))
}
}
implicit val decodeLong: Decoder[Long] = new Decoder[Long] {
def apply(m: MsgPack): Result[Long] = m.asLong match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Long", m))
}
}
implicit val decodeBigInt: Decoder[BigInt] = new Decoder[BigInt] {
def apply(m: MsgPack): Result[BigInt] = m.asBigInt match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("BigInt", m))
}
}
implicit val decodeDouble: Decoder[Double] = new Decoder[Double] {
def apply(m: MsgPack): Result[Double] = m.asDouble match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Double", m))
}
}
implicit val decodeFloat: Decoder[Float] = new Decoder[Float] {
def apply(m: MsgPack): Result[Float] = m.asFloat match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Float", m))
}
}
implicit val decodeChar: Decoder[Char] = new Decoder[Char] {
def apply(m: MsgPack): Result[Char] = m.asChar match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("Char", m))
}
}
implicit val decodeString: Decoder[String] = new Decoder[String] {
def apply(m: MsgPack): Result[String] = m.asString match {
case Some(a) => Right(a)
case _ => Left(TypeMismatchError("String", m))
}
}
implicit def decodeSome[A](implicit decodeA: Decoder[A]): Decoder[Some[A]] =
new Decoder[Some[A]] {
def apply(m: MsgPack): Result[Some[A]] =
decodeA(m) match {
case Right(v) => Right(Some(v))
case Left(e) => Left(e)
}
}
implicit val decodeNone: Decoder[None.type] =
new Decoder[None.type] {
def apply(m: MsgPack): Result[None.type] = Right(None)
}
implicit def decodeOption[A](implicit A: Decoder[A]): Decoder[Option[A]] =
new Decoder[Option[A]] {
def apply(m: MsgPack): Result[Option[A]] =
if (m.isNil || m.isEmpty)
Right(None)
else
A(m) match {
case Right(v) => Right(Option(v))
case Left(e) => Left(e)
}
}
@inline private[this] def decodeContainer[C[_], A](implicit
decodeA: Decoder[A],
factoryA: Factory[A, C[A]]): Decoder[C[A]] =
new Decoder[C[A]] {
def apply(m: MsgPack): Result[C[A]] = {
@tailrec def loop(it: Iterator[MsgPack], b: mutable.Builder[A, C[A]]): Result[C[A]] = {
if (!it.hasNext) Right(b.result())
else
decodeA(it.next()) match {
case Right(aa) => loop(it, b += aa)
case Left(e) => Left(e)
}
}
if (m.isNil || m.isEmpty)
Right(factoryA.newBuilder.result())
else
m.asVector match {
case Some(a) => loop(a.iterator, factoryA.newBuilder)
case _ => Left(TypeMismatchError(s"C[A]", m))
}
}
}
implicit def decodeSeq[A: Decoder]: Decoder[Seq[A]] = decodeContainer[Seq, A]
implicit def decodeSet[A: Decoder]: Decoder[Set[A]] = decodeContainer[Set, A]
implicit def decodeList[A: Decoder]: Decoder[List[A]] = decodeContainer[List, A]
implicit def decodeVector[A: Decoder]: Decoder[Vector[A]] = decodeContainer[Vector, A]
implicit def decodeMapLike[M[_, _] <: Map[K, V], K, V](implicit
decodeK: Decoder[K],
decodeV: Decoder[V],
factoryKV: Factory[(K, V), M[K, V]]): Decoder[M[K, V]] =
new Decoder[M[K, V]] {
def apply(m: MsgPack): Result[M[K, V]] = {
@tailrec def loop(it: Iterator[(MsgPack, MsgPack)], b: mutable.Builder[(K, V), M[K, V]]): Result[M[K, V]] = {
if (!it.hasNext) Right(b.result())
else {
val (k, v) = it.next()
decodeK(k) match {
case Right(kk) =>
decodeV(v) match {
case Right(vv) => loop(it, b += kk -> vv)
case Left(e) => Left(e)
}
case Left(e) => Left(e)
}
}
}
if (m.isNil || m.isEmpty)
Right(factoryKV.newBuilder.result())
else
m match {
case m: MsgPack.MMap => loop(m.iterator, factoryKV.newBuilder)
case _ => Left(TypeMismatchError(s"M[K, V]", m))
}
}
}
}
@imports[Decoder]
trait LowPriorityDecoder
© 2015 - 2025 Weber Informatics LLC | Privacy Policy