Created
May 24, 2020 23:37
-
-
Save elyphas/0ee7267766bf0662113ae2eda347183a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package encoderLabelledGeneric | |
import typesJson._ | |
import shapeless.{HList, ::, HNil, Lazy} | |
import shapeless.Witness | |
import shapeless.labelled.FieldType | |
import shapeless.LabelledGeneric | |
import shapeless._ | |
import syntax.singleton._ | |
import record._ | |
object HelpersLabelledGeneric2 { | |
trait JsonEncoder[A] { | |
def encode(value: A): JsonValue | |
} | |
object JsonEncoder { | |
def apply[A](implicit enc: JsonEncoder[A]): JsonEncoder[A] = enc | |
} | |
implicit val stringEncoder: JsonEncoder[String] = createEncoder( str => JsonString(str) ) | |
implicit val doubleEncoder: JsonEncoder[Double] = createEncoder( num => JsonNumber(num) ) | |
implicit val intEncoder: JsonEncoder[Int] = createEncoder( num => JsonNumber(num) ) | |
implicit val booleanEncoder: JsonEncoder[Boolean] = createEncoder( bool => JsonBoolean(bool) ) | |
implicit def listEncoder[A](implicit enc: JsonEncoder[A]): JsonEncoder[List[A]] = createEncoder( list => JsonArray( list.map( enc.encode ) ) ) | |
implicit def optionEncoder[A](implicit enc: JsonEncoder[A]): JsonEncoder[Option[A]] = createEncoder( opt => opt.map( enc.encode ).getOrElse( JsonNull ) ) | |
def createEncoder[A](func: A => JsonValue): JsonEncoder[A] = new JsonEncoder[A] { | |
def encode ( value: A ): JsonValue = func( value ) | |
} | |
trait JsonObjectEncoder[A] extends JsonEncoder[A] { | |
def encode(value: A): JsonObject | |
} | |
def createObjectEncoder[A](fn: A => JsonObject): JsonObjectEncoder[A] = new JsonObjectEncoder[A] { | |
def encode(value: A): JsonObject = fn ( value ) | |
} | |
implicit val hnilEncoder: JsonObjectEncoder[HNil] = createObjectEncoder ( hnil => JsonObject ( Nil ) ) | |
implicit def hlistObjectEncoder[K <: Symbol, H, T <: HList]( implicit witness: Witness.Aux[K], | |
hEncoder: Lazy[JsonEncoder[H]], | |
tEncoder: JsonObjectEncoder[T] | |
): JsonObjectEncoder[FieldType[K, H] :: T] = { | |
val fieldName: String = witness.value.name | |
createObjectEncoder { hlist => | |
val head = hEncoder.value.encode ( hlist.head ) | |
val tail = tEncoder.encode ( hlist.tail ) | |
JsonObject ( ( fieldName, head ) :: tail.fields ) | |
//JsonObject ( fieldName ->> head :: tail.fields ) | |
} | |
} | |
implicit def genericObjectEncoder[A, H]( implicit generic: LabelledGeneric.Aux[A, H], | |
hEncoder: Lazy[JsonObjectEncoder[H]] | |
): JsonEncoder[A] = | |
createObjectEncoder { value => hEncoder.value.encode ( generic.to ( value ) ) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment