diff --git a/core/src/main/scala/com/avsystem/commons/opaque/BaseOpaque.scala b/core/src/main/scala/com/avsystem/commons/opaque/BaseOpaque.scala index e3fda6fe7..dfc465f30 100644 --- a/core/src/main/scala/com/avsystem/commons/opaque/BaseOpaque.scala +++ b/core/src/main/scala/com/avsystem/commons/opaque/BaseOpaque.scala @@ -2,12 +2,15 @@ package com.avsystem.commons package opaque import com.avsystem.commons.opaque.Castable.<:> +import com.avsystem.commons.serialization.GenCodec private[opaque] trait BaseOpaque[From] extends Castable.Ops { trait Tag type Type - implicit protected final val castable: From <:> Type = new Castable[From, Type] - def apply(value: From): Type + + + implicit protected final val castable: From <:> Type = new Castable[From, Type] + implicit final def codec(implicit fromCodec: GenCodec[From]): GenCodec[Type] = wrapF(fromCodec) } diff --git a/core/src/main/scala/com/avsystem/commons/opaque/Castable.scala b/core/src/main/scala/com/avsystem/commons/opaque/Castable.scala index 43bb97fa2..919dccd2e 100644 --- a/core/src/main/scala/com/avsystem/commons/opaque/Castable.scala +++ b/core/src/main/scala/com/avsystem/commons/opaque/Castable.scala @@ -1,9 +1,7 @@ package com.avsystem.commons package opaque -private[opaque] final class Castable[A, B] { - @inline def apply(a: A): B = a.asInstanceOf[B] -} +private[opaque] final class Castable[A, B] private[opaque] object Castable { type <:>[A, B] = Castable[A, B] def apply[A, B](implicit ev: A <:> B): Castable[A, B] = ev diff --git a/core/src/test/scala/com/avsystem/commons/serialization/CodecTestData.scala b/core/src/test/scala/com/avsystem/commons/serialization/CodecTestData.scala index 7b3c94240..ac34d474a 100644 --- a/core/src/test/scala/com/avsystem/commons/serialization/CodecTestData.scala +++ b/core/src/test/scala/com/avsystem/commons/serialization/CodecTestData.scala @@ -4,6 +4,7 @@ package serialization import com.avsystem.commons.annotation.AnnotationAggregate import com.avsystem.commons.meta.{AutoOptionalParams, MacroInstances} import com.avsystem.commons.misc.{AutoNamedEnum, NamedEnumCompanion, TypedKey} +import com.avsystem.commons.opaque.{Opaque, Subopaque} import scala.annotation.meta.getter @@ -134,6 +135,9 @@ object CodecTestData { @transparent case class StringId(id: String) object StringId extends TransparentWrapperCompanion[String, StringId] + object SomeOpaque extends Opaque.Default[Int] + object SomeSubopaque extends Subopaque.Default[Int] + trait HasSomeStr { @name("some.str") def str: String @generated def someStrLen: Int = str.length diff --git a/core/src/test/scala/com/avsystem/commons/serialization/GenCodecRoundtripTest.scala b/core/src/test/scala/com/avsystem/commons/serialization/GenCodecRoundtripTest.scala index 27ba19dac..8dc26c1d6 100644 --- a/core/src/test/scala/com/avsystem/commons/serialization/GenCodecRoundtripTest.scala +++ b/core/src/test/scala/com/avsystem/commons/serialization/GenCodecRoundtripTest.scala @@ -72,6 +72,11 @@ abstract class GenCodecRoundtripTest extends AbstractCodecTest { testRoundtrip(StringId("lolfuu"), "lolfuu") } + test("opaque and subopaque") { + testRoundtrip(SomeOpaque(42)) + testRoundtrip(SomeSubopaque(42)) + } + test("case class") { testRoundtrip(SomeCaseClass("dafuq", List(1, 2, 3))) }