From d88940b90f1742e31bafcb29191c0ff95fb7a593 Mon Sep 17 00:00:00 2001 From: Gabriel Volpe Date: Wed, 7 Apr 2021 12:27:45 +0200 Subject: [PATCH] Improve keyEncoder and keyDecoder impl --- .../scala/shop/ext/circe/keyDecoder.scala | 10 ++++----- .../scala/shop/ext/circe/keyEncoder.scala | 21 +++++++++++-------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/modules/core/src/main/scala/shop/ext/circe/keyDecoder.scala b/modules/core/src/main/scala/shop/ext/circe/keyDecoder.scala index 3b204b85..947b402b 100644 --- a/modules/core/src/main/scala/shop/ext/circe/keyDecoder.scala +++ b/modules/core/src/main/scala/shop/ext/circe/keyDecoder.scala @@ -8,11 +8,11 @@ object keyDecoder extends Derivation[KeyDecoder] with NewTypeDerivation[KeyDecod type Typeclass[T] = KeyDecoder[T] def combine[T](ctx: CaseClass[KeyDecoder, T]): KeyDecoder[T] = new KeyDecoder[T] { - def apply(key: String): Option[T] = - ctx.parameters.toList match { - case (p :: _) => p.typeclass.apply(key).map(_.asInstanceOf[T]) - case _ => None - } + def apply(key: String): Option[T] = { + val parts = key.split("::") + if (parts.length != ctx.parameters.length) None + else ctx.constructMonadic(p => p.typeclass.apply(parts(p.index))) + } } def instance[T]: KeyDecoder[T] = macro Magnolia.gen[T] diff --git a/modules/core/src/main/scala/shop/ext/circe/keyEncoder.scala b/modules/core/src/main/scala/shop/ext/circe/keyEncoder.scala index efd3548f..8168e84b 100644 --- a/modules/core/src/main/scala/shop/ext/circe/keyEncoder.scala +++ b/modules/core/src/main/scala/shop/ext/circe/keyEncoder.scala @@ -2,18 +2,21 @@ package shop.ext.circe import derevo.{ Derivation, NewTypeDerivation } import io.circe.KeyEncoder -import magnolia.{ CaseClass, Magnolia } +import magnolia.{CaseClass, Magnolia, SealedTrait} -object keyEncoder extends Derivation[KeyEncoder] with NewTypeDerivation[KeyEncoder] { +class keyEncoder(sep: String = "::") { type Typeclass[T] = KeyEncoder[T] - def combine[T](ctx: CaseClass[KeyEncoder, T]): KeyEncoder[T] = new KeyEncoder[T] { - def apply(key: T): String = - ctx.parameters.toList match { - case (p :: _) => p.typeclass.apply(key.asInstanceOf[p.PType]) - case _ => "error" - } - } + def combine[T](ctx: CaseClass[KeyEncoder, T]): KeyEncoder[T] = + if (ctx.isObject) _ => ctx.typeName.short + else { cc => + ctx.parameters.view.map(p => p.typeclass(p.dereference(cc))).mkString(sep) + } + + def dispatch[T](ctx: SealedTrait[KeyEncoder, T]): KeyEncoder[T] = + obj => ctx.dispatch(obj)(sub => sub.typeclass(sub.cast(obj))) def instance[T]: KeyEncoder[T] = macro Magnolia.gen[T] } + +object keyEncoder extends keyEncoder("::") with Derivation[KeyEncoder] with NewTypeDerivation[KeyEncoder]