Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import shapeless.labelled.FieldType
- import shapeless.{::, DepFn2, HList, HNil, LabelledGeneric, Witness}
- import scala.collection.mutable
- // mock of sdk item
- class Item(val map: mutable.Map[String, Any] = mutable.Map[String, Any]()) {
- def getString(attrName: String): String = map.get(attrName).get.asInstanceOf[String]
- def getInt(attrName: String): Int = map.get(attrName).get.asInstanceOf[Int]
- def getBoolean(attrName: String): Boolean = map.get(attrName).get.asInstanceOf[Boolean]
- // def getMap(attrName: String): Map[String, String] = Map("attrName" -> "attrValue")
- def setString(attrName: String, value: String): Unit = map.put(attrName, value)
- def setInt(attrName: String, value: Int): Unit = map.put(attrName, value)
- def setBoolean(attrName: String, value: Boolean): Unit = map.put(attrName, value)
- override def toString() = map.toString()
- }
- trait ItemEncoder[A] extends DepFn2[String, A] {
- type Out = Item
- }
- object ItemEncoder {
- def apply[A](implicit encoder: ItemEncoder[A]): ItemEncoder[A] = encoder
- def instance[A](f: (String, A) => Item): ItemEncoder[A] =
- new ItemEncoder[A] {
- override def apply(attrName: String, value: A): Out = f(attrName, value)
- }
- }
- implicit val stringEncoder: ItemEncoder[String] =
- ItemEncoder.instance { (attrName, value) =>
- val item = new Item()
- item.setString(attrName, value)
- item
- }
- implicit val intEncoder: ItemEncoder[Int] =
- ItemEncoder.instance { (attrName, value) =>
- val item = new Item()
- item.setInt(attrName, value)
- item
- }
- implicit val booleanEncoder: ItemEncoder[Boolean] =
- ItemEncoder.instance { (attrName, value) =>
- val item = new Item()
- item.setBoolean(attrName, value)
- item
- }
- implicit val hnilEncoder: ItemEncoder[HNil] =
- ItemEncoder.instance((attrName, value) => new Item())
- def merge(i1: Item, i2: Item): Item = new Item(i1.map ++ i2.map)
- implicit def hlistEncoder[K <: Symbol, L, H, T <: HList](
- implicit
- witness: Witness.Aux[K],
- hEncoder: ItemEncoder[H],
- tEncoder: ItemEncoder[T]
- ): ItemEncoder[FieldType[K, H] :: T] = {
- ItemEncoder.instance { (_, value) =>
- val attrName = witness.value.name
- merge(hEncoder.apply(attrName, value.head), tEncoder.apply(attrName, value.tail))
- }
- }
- implicit def genericEncoder[A, R](
- implicit
- generic: LabelledGeneric.Aux[A, R],
- itemEncoder: ItemEncoder[R]
- ): ItemEncoder[A] =
- ItemEncoder.instance { (attrName, value) =>
- itemEncoder.apply(attrName, generic.to(value))
- }
- case class Person(name: String, age: Int, married: Boolean, manager: Boolean)
- case class IceCream(name: String, subName: String, price: Int)
- val genericPerson = LabelledGeneric[Person].to(Person("bob", 37, true, true))
- def encode[A](toEncode: A)(implicit itemEncoder: ItemEncoder[A]) =
- itemEncoder("", toEncode)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement