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

mess.codec.generic.DerivedEncoder.scala Maven / Gradle / Ivy

The newest version!
package mess.codec.generic

import export._
import mess.Encoder
import mess.ast.MsgPack
import shapeless._
import shapeless.labelled.FieldType

import scala.collection.mutable

trait DerivedEncoder[A] extends Encoder[A]

@exports
object DerivedEncoder extends LowPriorityDerivedEncoder

private[mess] trait LowPriorityDerivedEncoder {

  implicit final val encodeHNil: DerivedEncoder[HNil] =
    new DerivedEncoder[HNil] {
      def apply(a: HNil): MsgPack = MsgPack.MMap(mutable.HashMap.empty)
    }

  implicit final def encodeLabelledHList[K <: Symbol, H, T <: HList](
      implicit
      witK: Witness.Aux[K],
      encodeK: Encoder[K],
      encodeH: Encoder[H],
      encodeT: DerivedEncoder[T]): DerivedEncoder[FieldType[K, H] :: T] =
    new DerivedEncoder[FieldType[K, H] :: T] {
      def apply(a: FieldType[K, H] :: T): MsgPack =
        encodeT(a.tail) match {
          case tt: MsgPack.MMap => tt.add(encodeK(witK.value), encodeH(a.head))
          case tt               => tt
        }
    }

  implicit final val encodeCNil: DerivedEncoder[CNil] =
    new DerivedEncoder[CNil] {
      def apply(a: CNil): MsgPack = sys.error("Cannot encode CNil")
    }

  implicit final def encodeLabelledCCons[K <: Symbol, L, R <: Coproduct](
      implicit
      witK: Witness.Aux[K],
      encodeL: Encoder[L],
      encodeR: DerivedEncoder[R]): DerivedEncoder[FieldType[K, L] :+: R] =
    new DerivedEncoder[FieldType[K, L] :+: R] {
      def apply(a: FieldType[K, L] :+: R): MsgPack = a match {
        case Inl(h) => MsgPack.MMap(mutable.HashMap.empty += MsgPack.fromString(witK.value.name) -> encodeL(h))
        case Inr(t) => encodeR(t)
      }
    }

  implicit final def encodeGen[A, R](implicit
                                     gen: LabelledGeneric.Aux[A, R],
                                     encodeR: Lazy[DerivedEncoder[R]]): DerivedEncoder[A] =
    new DerivedEncoder[A] {
      def apply(a: A): MsgPack = encodeR.value(gen.to(a))
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy