Skip to content

Commit

Permalink
Add KeyDecoder for typelevel key modifying
Browse files Browse the repository at this point in the history
  • Loading branch information
tkrs committed Feb 1, 2019
1 parent dff36a2 commit 9daa743
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
12 changes: 12 additions & 0 deletions modules/core/src/main/scala/mess/KeyDecoder.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package mess

trait KeyDecoder[S <: Symbol] {
def apply(a: S): String
}

object KeyDecoder {

implicit def decodeSymbolKey[S <: Symbol]: KeyDecoder[S] = new KeyDecoder[S] {
def apply(m: S): String = m.name
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ private[mess] trait LowPriorityDerivedDecoder {
implicit final def decodeLabelledHList[K <: Symbol, H, T <: HList](
implicit
witK: Witness.Aux[K],
decodeK: mess.KeyDecoder[K],
decodeH: Decoder[H],
decodeT: DerivedDecoder[T]): DerivedDecoder[FieldType[K, H] :: T] =
new DerivedDecoder[FieldType[K, H] :: T] {
def apply(m: MsgPack): Decoder.Result[FieldType[K, H] :: T] = m match {
case MsgPack.MMap(a) =>
decodeT(m) match {
case Right(t) =>
val v = a.getOrElse(MsgPack.MString(witK.value.name), MsgPack.MNil)
val key = decodeK(witK.value)
val v = a.getOrElse(MsgPack.MString(key), MsgPack.MNil)
decodeH(v) match {
case Right(h) => Right(field[K](h) :: t)
case Left(e) => Left(e)
Expand Down
18 changes: 15 additions & 3 deletions modules/examples/src/main/scala/com/github/tkrs/example/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import mess._
import mess.ast.MsgPack
import mess.codec.generic._
import org.msgpack.core.MessagePack._
import shapeless.Witness

final case class Foo(age: Int, name: String)
object Foo {
type Name = Witness.`'name`.T

implicit val encodeName: Encoder[Name] = (n: Name) => MsgPack.fromString(n.name.toUpperCase())
implicit val decodeName: KeyDecoder[Name] = (s: Name) => s.name.toUpperCase()

implicit val encodeFoo: Encoder[Foo] = derivedEncoder[Foo]
implicit val decodeFoo: Decoder[Foo] = derivedDecoder[Foo]
}
Expand All @@ -21,9 +27,15 @@ object Main extends App {

val bar = Bar(Foo(2305, "Archimedes") :: Foo(411, "Johannes Kepler") :: Nil)

val packed = MsgPack.pack(Encoder[Bar].apply(bar), DEFAULT_PACKER_CONFIG)
val encoded = Encoder[Bar].apply(bar)
println(encoded)

val packed = MsgPack.pack(encoded, DEFAULT_PACKER_CONFIG)

val unpacked = MsgPack.unpack(packed, DEFAULT_UNPACKER_CONFIG)
println(unpacked)

val unpacked = Decoder[Bar].apply(MsgPack.unpack(packed, DEFAULT_UNPACKER_CONFIG))
val decoded = Decoder[Bar].apply(unpacked)

assert(Right(bar) == unpacked)
assert(Right(bar) == decoded)
}

0 comments on commit 9daa743

Please sign in to comment.