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

mist.api.encoding.ObjectEncoder.scala Maven / Gradle / Ivy

The newest version!
package mist.api.encoding

import mist.api.data.{JsData, JsMap}
import shadedshapeless.labelled.FieldType
import shadedshapeless._

import scala.annotation.implicitNotFound

@implicitNotFound(msg =
  "Couldn't find mist.api.encoding.ObjectEncoder[${A}]" +
  " Ensure that JsEncoder instances exists for it's fields" +
  " or add `import mist.api.encoding.defaults._`"
)
trait ObjectEncoder[A] { self =>
  def apply(a : A): JsMap
}

object ObjectEncoder {

  def apply[A](implicit enc: ObjectEncoder[A]): ObjectEncoder[A] = enc

  def create[A](f: A => JsMap): ObjectEncoder[A] = new ObjectEncoder[A] {
    override def apply(a: A): JsMap = f(a)
  }

  implicit val hNilEnc: ObjectEncoder[HNil] = ObjectEncoder.create[HNil](_ => JsMap.empty)

  implicit def hlistExt[K <: Symbol, H, T <: HList](implicit
    witness: Witness.Aux[K],
    lHenc: Lazy[JsEncoder[H]],
    tEnc: ObjectEncoder[T]
  ): ObjectEncoder[FieldType[K, H] :: T] = {
    val hEnc = lHenc.value
    val key = witness.value.name
    ObjectEncoder.create[FieldType[K, H] :: T](hlist => {
      val h = hEnc(hlist.head)
      val t = tEnc(hlist.tail)
      val values = (key -> h) +: t.fields
      JsMap(values: _*)
    })
  }

  implicit def labelled[A, H <: HList](implicit labGen: LabelledGeneric.Aux[A, H], enc: ObjectEncoder[H]): ObjectEncoder[A] =
    ObjectEncoder.create(a => enc(labGen.to(a)))
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy