From dc05f7a8ac738fe7da672427b67da862e8926b7e Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Thu, 28 Jan 2021 14:46:10 +0000 Subject: [PATCH 1/8] narrow type ef `encode` from `Any` to `AnyRef` --- modules/core/src/main/scala/vulcan/Codec.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index e1654054..e9491378 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -41,7 +41,7 @@ sealed abstract class Codec[A] { def schema: Either[AvroError, Schema] /** Attempts to encode the specified value using the provided schema. */ - def encode(a: A): Either[AvroError, Any] + def encode(a: A): Either[AvroError, AnyRef] /** Attempts to decode the specified value using the provided schema. */ def decode(value: Any, schema: Schema): Either[AvroError, A] @@ -565,7 +565,7 @@ object Codec extends CodecCompanionCompat { */ final def instance[A]( schema: Either[AvroError, Schema], - encode: A => Either[AvroError, Any], + encode: A => Either[AvroError, AnyRef], decode: (Any, Schema) => Either[AvroError, A] ): Codec[A] = { val _schema = schema @@ -576,7 +576,7 @@ object Codec extends CodecCompanionCompat { override final val schema: Either[AvroError, Schema] = _schema - override final def encode(a: A): Either[AvroError, Any] = + override final def encode(a: A): Either[AvroError, AnyRef] = _encode(a) override final def decode(value: Any, schema: Schema): Either[AvroError, A] = @@ -594,7 +594,7 @@ object Codec extends CodecCompanionCompat { expectedValueType: String, decodingTypeName: String, schema: Either[AvroError, Schema], - encode: A => Either[AvroError, Any], + encode: A => Either[AvroError, AnyRef], decode: PartialFunction[(Any, Schema), Either[AvroError, A]] ): Codec[A] = { instance( From 1bef917ba5375505c5e47f2ce7b2ae99e04a34f1 Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Thu, 28 Jan 2021 14:51:59 +0000 Subject: [PATCH 2/8] Add Repr type to codec --- .../core/src/main/scala/vulcan/Codec.scala | 45 ++++++++++++------- .../main/scala/vulcan/generic/package.scala | 4 +- .../test/scala/vulcan/generic/CodecSpec.scala | 2 +- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index e9491378..38a58d59 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -36,12 +36,13 @@ import scala.util.Try "could not find implicit Codec[${A}]; ensure no imports are missing or manually define an instance" ) sealed abstract class Codec[A] { + type Repr <: AnyRef /** The schema or an error if the schema could not be generated. */ def schema: Either[AvroError, Schema] /** Attempts to encode the specified value using the provided schema. */ - def encode(a: A): Either[AvroError, AnyRef] + def encode(a: A): Either[AvroError, Repr] /** Attempts to decode the specified value using the provided schema. */ def decode(value: Any, schema: Schema): Either[AvroError, A] @@ -51,7 +52,7 @@ sealed abstract class Codec[A] { * for encoding and decoding, mapping back-and-forth * between types `A` and `B`. */ - final def imap[B](f: A => B)(g: B => A): Codec[B] = + final def imap[B](f: A => B)(g: B => A): Codec.Aux[B, Repr] = Codec.instance( schema, b => encode(g(b)), @@ -66,7 +67,7 @@ sealed abstract class Codec[A] { * Similar to [[Codec#imap]], except the mapping from * `A` to `B` might be unsuccessful. */ - final def imapError[B](f: A => Either[AvroError, B])(g: B => A): Codec[B] = + final def imapError[B](f: A => Either[AvroError, B])(g: B => A): Codec.Aux[B, Repr] = Codec.instance( schema, b => encode(g(b)), @@ -81,10 +82,10 @@ sealed abstract class Codec[A] { * Similar to [[Codec#imap]], except the mapping from * `A` to `B` might be unsuccessful. */ - final def imapTry[B](f: A => Try[B])(g: B => A): Codec[B] = + final def imapTry[B](f: A => Try[B])(g: B => A): Codec.Aux[B, Repr] = imapError(f(_).toEither.leftMap(AvroError.fromThrowable))(g) - private[vulcan] def withDecodingTypeName(decodingTypeName: String): Codec[A] = + private[vulcan] def withDecodingTypeName(decodingTypeName: String): Codec.Aux[A, Repr] = Codec.instance( schema, encode, @@ -131,6 +132,10 @@ sealed abstract class Codec[A] { */ object Codec extends CodecCompanionCompat { + type Aux[A, Repr0 <: AnyRef] = Codec[A] { + type Repr = Repr0 + } + /** * Returns the [[Codec]] for the specified type. * @@ -209,7 +214,7 @@ object Codec extends CodecCompanionCompat { "Collection", "Chain", codec.schema.map(Schema.createArray), - _.toList.traverse(codec.encode).map(_.asJava), { + _.toList.traverse(codec.encode(_)).map(_.asJava), { case (collection: java.util.Collection[_], schema) => collection.asScala.toList .traverse(codec.decode(_, schema.getElementType())) @@ -563,20 +568,22 @@ object Codec extends CodecCompanionCompat { * * @group Create */ - final def instance[A]( + final def instance[A, Repr0 <: AnyRef]( schema: Either[AvroError, Schema], - encode: A => Either[AvroError, AnyRef], + encode: A => Either[AvroError, Repr0], decode: (Any, Schema) => Either[AvroError, A] - ): Codec[A] = { + ): Codec.Aux[A, Repr0] = { val _schema = schema val _encode = encode val _decode = decode new Codec[A] { + type Repr = Repr0 + override final val schema: Either[AvroError, Schema] = _schema - override final def encode(a: A): Either[AvroError, AnyRef] = + override final def encode(a: A): Either[AvroError, Repr] = _encode(a) override final def decode(value: Any, schema: Schema): Either[AvroError, A] = @@ -590,13 +597,13 @@ object Codec extends CodecCompanionCompat { } } - private[vulcan] final def instanceForTypes[A]( + private[vulcan] final def instanceForTypes[A, Repr <: AnyRef]( expectedValueType: String, decodingTypeName: String, schema: Either[AvroError, Schema], - encode: A => Either[AvroError, AnyRef], + encode: A => Either[AvroError, Repr], decode: PartialFunction[(Any, Schema), Either[AvroError, A]] - ): Codec[A] = { + ): Codec.Aux[A, Repr] = { instance( schema, encode, @@ -667,7 +674,7 @@ object Codec extends CodecCompanionCompat { "Collection", "List", codec.schema.map(Schema.createArray), - _.traverse(codec.encode).map(_.asJava), { + _.traverse(codec.encode(_)).map(_.asJava), { case (collection: java.util.Collection[_], schema) => collection.asScala.toList.traverse(codec.decode(_, schema.getElementType())) } @@ -1080,7 +1087,7 @@ object Codec extends CodecCompanionCompat { a => alts .foldMapK { alt => - alt.prism.getOption(a).map(alt.codec.encode) + alt.prism.getOption(a).map(alt.codec.encode(_)) } .getOrElse { Left(AvroError.encodeExhaustedAlternatives(a, None)) @@ -1178,7 +1185,7 @@ object Codec extends CodecCompanionCompat { "Collection", "Vector", codec.schema.map(Schema.createArray), - _.traverse(codec.encode).map(_.asJava), { + _.traverse(codec.encode(_)).map(_.asJava), { case (collection: java.util.Collection[_], schema) => collection.asScala.toVector.traverse(codec.decode(_, schema.getElementType())) } @@ -1199,6 +1206,12 @@ object Codec extends CodecCompanionCompat { implicit final def codecShow[A]: Show[Codec[A]] = Show.fromToString + /** + * @group Cats + */ + implicit final def codecAuxShow[A, Repr <: AnyRef]: Show[Codec.Aux[A, Repr]] = + Show.fromToString + /** * @group Create */ diff --git a/modules/generic/src/main/scala/vulcan/generic/package.scala b/modules/generic/src/main/scala/vulcan/generic/package.scala index 00b90cf3..29e66e01 100644 --- a/modules/generic/src/main/scala/vulcan/generic/package.scala +++ b/modules/generic/src/main/scala/vulcan/generic/package.scala @@ -45,8 +45,8 @@ package object generic { } }, _.eliminate( - headCodec.encode, - tailCodec.value.encode + headCodec.encode(_), + tailCodec.value.encode(_) ), (value, schema) => { val schemaTypes = diff --git a/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala b/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala index fb247537..b54ada79 100644 --- a/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala +++ b/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala @@ -61,7 +61,7 @@ final class CodecSpec extends AnyFunSpec with ScalaCheckPropertyChecks with Eith coproductCodec[Int, CNil]( Codec.int, shapeless.Lazy { - Codec.instance[CNil]( + Codec.instance[CNil, Null]( Right(SchemaBuilder.builder().nullType()), _ => Left(AvroError("encode")), (_, _) => Left(AvroError("decode")) From 9b765e764051a43ab28aaffc4bbfa0cb84afe39f Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Thu, 28 Jan 2021 15:03:55 +0000 Subject: [PATCH 3/8] use Aux types for codecs --- .../core/src/main/scala/vulcan/Codec.scala | 89 +++++++++++-------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index 38a58d59..3f5c0acd 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -147,7 +147,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val boolean: Codec[Boolean] = + implicit final val boolean: Codec.Aux[Boolean, java.lang.Boolean] = Codec.instanceForTypes( "Boolean", "Boolean", @@ -161,7 +161,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final lazy val byte: Codec[Byte] = { + implicit final lazy val byte: Codec.Aux[Byte, java.lang.Integer] = { val min: Int = Byte.MinValue.toInt val max: Int = Byte.MaxValue.toInt Codec.int @@ -176,7 +176,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val bytes: Codec[Array[Byte]] = + implicit final val bytes: Codec.Aux[Array[Byte], ByteBuffer] = Codec.instance( Right(SchemaBuilder.builder().bytesType()), ByteBuffer.wrap(_).asRight, @@ -209,7 +209,9 @@ object Codec extends CodecCompanionCompat { /** * @group Cats */ - implicit final def chain[A](implicit codec: Codec[A]): Codec[Chain[A]] = + implicit final def chain[A]( + implicit codec: Codec[A] + ): Codec.Aux[Chain[A], java.util.Collection[codec.Repr]] = Codec.instanceForTypes( "Collection", "Chain", @@ -225,7 +227,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val char: Codec[Char] = + implicit final val char: Codec.Aux[Char, Utf8] = Codec.instanceForTypes( "Utf8", "Char", @@ -246,7 +248,7 @@ object Codec extends CodecCompanionCompat { final def decimal( precision: Int, scale: Int - ): Codec[BigDecimal] = { + ): Codec.Aux[BigDecimal, ByteBuffer] = { val conversion = new Conversions.DecimalConversion() val logicalType = LogicalTypes.decimal(precision, scale) val schema = AvroError.catchNonFatal { @@ -307,7 +309,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val double: Codec[Double] = + implicit final val double: Codec.Aux[Double, java.lang.Double] = Codec.instance( Right(SchemaBuilder.builder().doubleType()), java.lang.Double.valueOf(_).asRight, @@ -346,7 +348,7 @@ object Codec extends CodecCompanionCompat { implicit final def either[A, B]( implicit codecA: Codec[A], codecB: Codec[B] - ): Codec[Either[A, B]] = + ): Codec.Aux[Either[A, B], AnyRef] = Codec.union(alt => alt[Left[A, B]] |+| alt[Right[A, B]]) /** @@ -372,7 +374,7 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - ): Codec[A] = { + ): Codec.Aux[A, AnyRef] = { val typeName = if (namespace.isEmpty) name else s"$namespace.$name" val schema = AvroError.catchNonFatal { props.toChain.map { props => @@ -429,7 +431,8 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - ): Codec[A] = enumeration(name, namespace, symbols, encode, decode, default, doc, aliases, props) + ): Codec.Aux[A, AnyRef] = + enumeration(name, namespace, symbols, encode, decode, default, doc, aliases, props) /** * Returns a new fixed [[Codec]] for type `A`. @@ -450,7 +453,7 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - ): Codec[A] = { + ): Codec.Aux[A, GenericFixed] = { val typeName = if (namespace.isEmpty) name else s"$namespace.$name" val schema = AvroError.catchNonFatal { props.toChain.map { props => @@ -474,7 +477,7 @@ object Codec extends CodecCompanionCompat { val bytes = encode(a) if (bytes.length <= size) { val buffer = ByteBuffer.allocate(size).put(bytes) - schema.map(GenericData.get().createFixed(null, buffer.array(), _)) + schema.map(new GenericData.Fixed(_, buffer.array())) } else { Left(AvroError.encodeExceedsFixedSize(bytes.length, size, typeName)) } @@ -499,7 +502,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val float: Codec[Float] = + implicit final val float: Codec.Aux[Float, java.lang.Float] = Codec.instance( Right(SchemaBuilder.builder().floatType()), java.lang.Float.valueOf(_).asRight, @@ -632,7 +635,7 @@ object Codec extends CodecCompanionCompat { /** * @group JavaTime */ - implicit final val instant: Codec[Instant] = + implicit final val instant: Codec.Aux[Instant, java.lang.Long] = Codec.instanceForTypes( "Long", "Instant", @@ -649,7 +652,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val int: Codec[Int] = + implicit final val int: Codec.Aux[Int, java.lang.Integer] = Codec.instanceForTypes( "Int", "Int", @@ -663,13 +666,15 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final def left[A, B](implicit codec: Codec[A]): Codec[Left[A, B]] = + implicit final def left[A, B](implicit codec: Codec[A]): Codec.Aux[Left[A, B], codec.Repr] = codec.imap(Left[A, B](_))(_.value) /** * @group Collection */ - implicit final def list[A](implicit codec: Codec[A]): Codec[List[A]] = + implicit final def list[A]( + implicit codec: Codec[A] + ): Codec.Aux[List[A], java.util.Collection[codec.Repr]] = Codec.instanceForTypes( "Collection", "List", @@ -683,7 +688,7 @@ object Codec extends CodecCompanionCompat { /** * @group JavaTime */ - implicit final val localDate: Codec[LocalDate] = + implicit final val localDate: Codec.Aux[LocalDate, java.lang.Integer] = Codec.instanceForTypes( "Integer", "LocalDate", @@ -700,7 +705,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val long: Codec[Long] = + implicit final val long: Codec.Aux[Long, java.lang.Long] = Codec.instance( Right(SchemaBuilder.builder().longType()), java.lang.Long.valueOf(_).asRight, @@ -732,7 +737,9 @@ object Codec extends CodecCompanionCompat { /** * @group Collection */ - implicit final def map[A](implicit codec: Codec[A]): Codec[Map[String, A]] = + implicit final def map[A]( + implicit codec: Codec[A] + ): Codec.Aux[Map[String, A], java.util.Map[Utf8, codec.Repr]] = Codec.instanceForTypes( "java.util.Map", "Map", @@ -762,7 +769,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val none: Codec[None.type] = + implicit final val none: Codec.Aux[None.type, Null] = Codec.instanceForTypes( "null", "None", @@ -774,7 +781,9 @@ object Codec extends CodecCompanionCompat { /** * @group Cats */ - implicit final def nonEmptyChain[A](implicit codec: Codec[A]): Codec[NonEmptyChain[A]] = + implicit final def nonEmptyChain[A]( + implicit codec: Codec[A] + ): Codec.Aux[NonEmptyChain[A], java.util.Collection[codec.Repr]] = Codec .chain[A] .imapError( @@ -785,7 +794,9 @@ object Codec extends CodecCompanionCompat { /** * @group Cats */ - implicit final def nonEmptyList[A](implicit codec: Codec[A]): Codec[NonEmptyList[A]] = + implicit final def nonEmptyList[A]( + implicit codec: Codec[A] + ): Codec.Aux[NonEmptyList[A], java.util.Collection[codec.Repr]] = Codec .list[A] .imapError( @@ -799,7 +810,7 @@ object Codec extends CodecCompanionCompat { implicit final def nonEmptySet[A]( implicit codec: Codec[A], ordering: Ordering[A] - ): Codec[NonEmptySet[A]] = + ): Codec.Aux[NonEmptySet[A], java.util.Collection[codec.Repr]] = Codec .list[A] .imapError( @@ -813,7 +824,9 @@ object Codec extends CodecCompanionCompat { /** * @group Cats */ - implicit final def nonEmptyVector[A](implicit codec: Codec[A]): Codec[NonEmptyVector[A]] = + implicit final def nonEmptyVector[A]( + implicit codec: Codec[A] + ): Codec.Aux[NonEmptyVector[A], java.util.Collection[codec.Repr]] = Codec .vector[A] .imapError( @@ -838,7 +851,7 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - )(f: FieldBuilder[A] => FreeApplicative[Field[A, *], A]): Codec[A] = { + )(f: FieldBuilder[A] => FreeApplicative[Field[A, *], A]): Codec.Aux[A, GenericRecord] = { val typeName = if (namespace.isEmpty) name else s"$namespace.$name" val free = f(FieldBuilder.instance) val schema = AvroError.catchNonFatal { @@ -952,13 +965,15 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final def right[A, B](implicit codec: Codec[B]): Codec[Right[A, B]] = + implicit final def right[A, B](implicit codec: Codec[B]): Codec.Aux[Right[A, B], codec.Repr] = codec.imap(Right[A, B](_))(_.value) /** * @group Collection */ - implicit final def seq[A](implicit codec: Codec[A]): Codec[Seq[A]] = + implicit final def seq[A]( + implicit codec: Codec[A] + ): Codec.Aux[Seq[A], java.util.Collection[codec.Repr]] = Codec .list[A] .imap[Seq[A]](_.toSeq)(_.toList) @@ -967,7 +982,9 @@ object Codec extends CodecCompanionCompat { /** * @group Collection */ - implicit final def set[A](implicit codec: Codec[A]): Codec[Set[A]] = + implicit final def set[A]( + implicit codec: Codec[A] + ): Codec.Aux[Set[A], java.util.Collection[codec.Repr]] = Codec .list[A] .imap(_.toSet)(_.toList) @@ -976,7 +993,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val short: Codec[Short] = { + implicit final val short: Codec.Aux[Short, java.lang.Integer] = { val min: Int = Short.MinValue.toInt val max: Int = Short.MaxValue.toInt Codec.int @@ -991,13 +1008,13 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final def some[A](implicit codec: Codec[A]): Codec[Some[A]] = + implicit final def some[A](implicit codec: Codec[A]): Codec.Aux[Some[A], codec.Repr] = codec.imap(Some(_))(_.value) /** * @group General */ - implicit final val string: Codec[String] = + implicit final val string: Codec.Aux[String, Utf8] = Codec.instance( Right(SchemaBuilder.builder().stringType()), new Utf8(_).asRight, @@ -1074,7 +1091,7 @@ object Codec extends CodecCompanionCompat { * * @group Create */ - final def union[A](f: AltBuilder[A] => Chain[Alt[A]]): Codec[A] = { + final def union[A](f: AltBuilder[A] => Chain[Alt[A]]): Codec.Aux[A, AnyRef] = { val alts = f(AltBuilder.instance) val schema = AvroError.catchNonFatal { alts.toList @@ -1161,7 +1178,7 @@ object Codec extends CodecCompanionCompat { /** * @group JavaUtil */ - implicit final val uuid: Codec[UUID] = + implicit final val uuid: Codec.Aux[UUID, Utf8] = Codec.instanceForTypes( "Utf8", "UUID", @@ -1180,7 +1197,9 @@ object Codec extends CodecCompanionCompat { /** * @group Collection */ - implicit final def vector[A](implicit codec: Codec[A]): Codec[Vector[A]] = + implicit final def vector[A]( + implicit codec: Codec[A] + ): Codec.Aux[Vector[A], java.util.Collection[codec.Repr]] = Codec.instanceForTypes( "Collection", "Vector", From 8f4a6d5a59cadae63bc6667fe06191a3838f3cbd Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Thu, 28 Jan 2021 15:26:41 +0000 Subject: [PATCH 4/8] narrow type we encode Array as --- .../core/src/main/scala/vulcan/Codec.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index 3f5c0acd..58832439 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -211,7 +211,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def chain[A]( implicit codec: Codec[A] - ): Codec.Aux[Chain[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[Chain[A], java.util.List[codec.Repr]] = Codec.instanceForTypes( "Collection", "Chain", @@ -674,7 +674,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def list[A]( implicit codec: Codec[A] - ): Codec.Aux[List[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[List[A], java.util.List[codec.Repr]] = Codec.instanceForTypes( "Collection", "List", @@ -783,7 +783,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def nonEmptyChain[A]( implicit codec: Codec[A] - ): Codec.Aux[NonEmptyChain[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[NonEmptyChain[A], java.util.List[codec.Repr]] = Codec .chain[A] .imapError( @@ -796,7 +796,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def nonEmptyList[A]( implicit codec: Codec[A] - ): Codec.Aux[NonEmptyList[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[NonEmptyList[A], java.util.List[codec.Repr]] = Codec .list[A] .imapError( @@ -810,7 +810,7 @@ object Codec extends CodecCompanionCompat { implicit final def nonEmptySet[A]( implicit codec: Codec[A], ordering: Ordering[A] - ): Codec.Aux[NonEmptySet[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[NonEmptySet[A], java.util.List[codec.Repr]] = Codec .list[A] .imapError( @@ -826,7 +826,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def nonEmptyVector[A]( implicit codec: Codec[A] - ): Codec.Aux[NonEmptyVector[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[NonEmptyVector[A], java.util.List[codec.Repr]] = Codec .vector[A] .imapError( @@ -973,7 +973,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def seq[A]( implicit codec: Codec[A] - ): Codec.Aux[Seq[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[Seq[A], java.util.List[codec.Repr]] = Codec .list[A] .imap[Seq[A]](_.toSeq)(_.toList) @@ -984,7 +984,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def set[A]( implicit codec: Codec[A] - ): Codec.Aux[Set[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[Set[A], java.util.List[codec.Repr]] = Codec .list[A] .imap(_.toSet)(_.toList) @@ -1166,7 +1166,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val unit: Codec[Unit] = + implicit final val unit: Codec.Aux[Unit, Null] = Codec.instanceForTypes( "null", "Unit", @@ -1199,7 +1199,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def vector[A]( implicit codec: Codec[A] - ): Codec.Aux[Vector[A], java.util.Collection[codec.Repr]] = + ): Codec.Aux[Vector[A], java.util.List[codec.Repr]] = Codec.instanceForTypes( "Collection", "Vector", From f1cc6bbdab45d0f16ff8c6eeee32175fc8350bf0 Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Thu, 28 Jan 2021 15:30:41 +0000 Subject: [PATCH 5/8] reverse order of Aux parameters --- .../core/src/main/scala/vulcan/Codec.scala | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index 58832439..ecb49d8b 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -52,7 +52,7 @@ sealed abstract class Codec[A] { * for encoding and decoding, mapping back-and-forth * between types `A` and `B`. */ - final def imap[B](f: A => B)(g: B => A): Codec.Aux[B, Repr] = + final def imap[B](f: A => B)(g: B => A): Codec.Aux[Repr, B] = Codec.instance( schema, b => encode(g(b)), @@ -67,7 +67,7 @@ sealed abstract class Codec[A] { * Similar to [[Codec#imap]], except the mapping from * `A` to `B` might be unsuccessful. */ - final def imapError[B](f: A => Either[AvroError, B])(g: B => A): Codec.Aux[B, Repr] = + final def imapError[B](f: A => Either[AvroError, B])(g: B => A): Codec.Aux[Repr, B] = Codec.instance( schema, b => encode(g(b)), @@ -82,10 +82,10 @@ sealed abstract class Codec[A] { * Similar to [[Codec#imap]], except the mapping from * `A` to `B` might be unsuccessful. */ - final def imapTry[B](f: A => Try[B])(g: B => A): Codec.Aux[B, Repr] = + final def imapTry[B](f: A => Try[B])(g: B => A): Codec.Aux[Repr, B] = imapError(f(_).toEither.leftMap(AvroError.fromThrowable))(g) - private[vulcan] def withDecodingTypeName(decodingTypeName: String): Codec.Aux[A, Repr] = + private[vulcan] def withDecodingTypeName(decodingTypeName: String): Codec.Aux[Repr, A] = Codec.instance( schema, encode, @@ -132,7 +132,7 @@ sealed abstract class Codec[A] { */ object Codec extends CodecCompanionCompat { - type Aux[A, Repr0 <: AnyRef] = Codec[A] { + type Aux[Repr0 <: AnyRef, A] = Codec[A] { type Repr = Repr0 } @@ -141,13 +141,13 @@ object Codec extends CodecCompanionCompat { * * @group Utilities */ - final def apply[A](implicit codec: Codec[A]): Codec[A] = + final def apply[A](implicit codec: Codec[A]): codec.type = codec /** * @group General */ - implicit final val boolean: Codec.Aux[Boolean, java.lang.Boolean] = + implicit final val boolean: Codec.Aux[java.lang.Boolean, Boolean] = Codec.instanceForTypes( "Boolean", "Boolean", @@ -161,7 +161,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final lazy val byte: Codec.Aux[Byte, java.lang.Integer] = { + implicit final lazy val byte: Codec.Aux[java.lang.Integer, Byte] = { val min: Int = Byte.MinValue.toInt val max: Int = Byte.MaxValue.toInt Codec.int @@ -176,7 +176,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val bytes: Codec.Aux[Array[Byte], ByteBuffer] = + implicit final val bytes: Codec.Aux[ByteBuffer, Array[Byte]] = Codec.instance( Right(SchemaBuilder.builder().bytesType()), ByteBuffer.wrap(_).asRight, @@ -211,7 +211,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def chain[A]( implicit codec: Codec[A] - ): Codec.Aux[Chain[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], Chain[A]] = Codec.instanceForTypes( "Collection", "Chain", @@ -227,7 +227,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val char: Codec.Aux[Char, Utf8] = + implicit final val char: Codec.Aux[Utf8, Char] = Codec.instanceForTypes( "Utf8", "Char", @@ -248,7 +248,7 @@ object Codec extends CodecCompanionCompat { final def decimal( precision: Int, scale: Int - ): Codec.Aux[BigDecimal, ByteBuffer] = { + ): Codec.Aux[ByteBuffer, BigDecimal] = { val conversion = new Conversions.DecimalConversion() val logicalType = LogicalTypes.decimal(precision, scale) val schema = AvroError.catchNonFatal { @@ -309,7 +309,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val double: Codec.Aux[Double, java.lang.Double] = + implicit final val double: Codec.Aux[java.lang.Double, Double] = Codec.instance( Right(SchemaBuilder.builder().doubleType()), java.lang.Double.valueOf(_).asRight, @@ -348,7 +348,7 @@ object Codec extends CodecCompanionCompat { implicit final def either[A, B]( implicit codecA: Codec[A], codecB: Codec[B] - ): Codec.Aux[Either[A, B], AnyRef] = + ): Codec.Aux[AnyRef, Either[A, B]] = Codec.union(alt => alt[Left[A, B]] |+| alt[Right[A, B]]) /** @@ -374,7 +374,7 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - ): Codec.Aux[A, AnyRef] = { + ): Codec.Aux[AnyRef, A] = { val typeName = if (namespace.isEmpty) name else s"$namespace.$name" val schema = AvroError.catchNonFatal { props.toChain.map { props => @@ -431,7 +431,7 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - ): Codec.Aux[A, AnyRef] = + ): Codec.Aux[AnyRef, A] = enumeration(name, namespace, symbols, encode, decode, default, doc, aliases, props) /** @@ -453,7 +453,7 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - ): Codec.Aux[A, GenericFixed] = { + ): Codec.Aux[GenericFixed, A] = { val typeName = if (namespace.isEmpty) name else s"$namespace.$name" val schema = AvroError.catchNonFatal { props.toChain.map { props => @@ -502,7 +502,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val float: Codec.Aux[Float, java.lang.Float] = + implicit final val float: Codec.Aux[java.lang.Float, Float] = Codec.instance( Right(SchemaBuilder.builder().floatType()), java.lang.Float.valueOf(_).asRight, @@ -575,7 +575,7 @@ object Codec extends CodecCompanionCompat { schema: Either[AvroError, Schema], encode: A => Either[AvroError, Repr0], decode: (Any, Schema) => Either[AvroError, A] - ): Codec.Aux[A, Repr0] = { + ): Codec.Aux[Repr0, A] = { val _schema = schema val _encode = encode val _decode = decode @@ -606,7 +606,7 @@ object Codec extends CodecCompanionCompat { schema: Either[AvroError, Schema], encode: A => Either[AvroError, Repr], decode: PartialFunction[(Any, Schema), Either[AvroError, A]] - ): Codec.Aux[A, Repr] = { + ): Codec.Aux[Repr, A] = { instance( schema, encode, @@ -635,7 +635,7 @@ object Codec extends CodecCompanionCompat { /** * @group JavaTime */ - implicit final val instant: Codec.Aux[Instant, java.lang.Long] = + implicit final val instant: Codec.Aux[java.lang.Long, Instant] = Codec.instanceForTypes( "Long", "Instant", @@ -652,7 +652,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val int: Codec.Aux[Int, java.lang.Integer] = + implicit final val int: Codec.Aux[java.lang.Integer, Int] = Codec.instanceForTypes( "Int", "Int", @@ -666,7 +666,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final def left[A, B](implicit codec: Codec[A]): Codec.Aux[Left[A, B], codec.Repr] = + implicit final def left[A, B](implicit codec: Codec[A]): Codec.Aux[codec.Repr, Left[A, B]] = codec.imap(Left[A, B](_))(_.value) /** @@ -674,7 +674,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def list[A]( implicit codec: Codec[A] - ): Codec.Aux[List[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], List[A]] = Codec.instanceForTypes( "Collection", "List", @@ -688,7 +688,7 @@ object Codec extends CodecCompanionCompat { /** * @group JavaTime */ - implicit final val localDate: Codec.Aux[LocalDate, java.lang.Integer] = + implicit final val localDate: Codec.Aux[java.lang.Integer, LocalDate] = Codec.instanceForTypes( "Integer", "LocalDate", @@ -705,7 +705,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val long: Codec.Aux[Long, java.lang.Long] = + implicit final val long: Codec.Aux[java.lang.Long, Long] = Codec.instance( Right(SchemaBuilder.builder().longType()), java.lang.Long.valueOf(_).asRight, @@ -739,7 +739,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def map[A]( implicit codec: Codec[A] - ): Codec.Aux[Map[String, A], java.util.Map[Utf8, codec.Repr]] = + ): Codec.Aux[java.util.Map[Utf8, codec.Repr], Map[String, A]] = Codec.instanceForTypes( "java.util.Map", "Map", @@ -769,7 +769,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val none: Codec.Aux[None.type, Null] = + implicit final val none: Codec.Aux[Null, None.type] = Codec.instanceForTypes( "null", "None", @@ -783,7 +783,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def nonEmptyChain[A]( implicit codec: Codec[A] - ): Codec.Aux[NonEmptyChain[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], NonEmptyChain[A]] = Codec .chain[A] .imapError( @@ -796,7 +796,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def nonEmptyList[A]( implicit codec: Codec[A] - ): Codec.Aux[NonEmptyList[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], NonEmptyList[A]] = Codec .list[A] .imapError( @@ -810,7 +810,7 @@ object Codec extends CodecCompanionCompat { implicit final def nonEmptySet[A]( implicit codec: Codec[A], ordering: Ordering[A] - ): Codec.Aux[NonEmptySet[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], NonEmptySet[A]] = Codec .list[A] .imapError( @@ -826,7 +826,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def nonEmptyVector[A]( implicit codec: Codec[A] - ): Codec.Aux[NonEmptyVector[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], NonEmptyVector[A]] = Codec .vector[A] .imapError( @@ -851,7 +851,7 @@ object Codec extends CodecCompanionCompat { doc: Option[String] = None, aliases: Seq[String] = Seq.empty, props: Props = Props.empty - )(f: FieldBuilder[A] => FreeApplicative[Field[A, *], A]): Codec.Aux[A, GenericRecord] = { + )(f: FieldBuilder[A] => FreeApplicative[Field[A, *], A]): Codec.Aux[GenericRecord, A] = { val typeName = if (namespace.isEmpty) name else s"$namespace.$name" val free = f(FieldBuilder.instance) val schema = AvroError.catchNonFatal { @@ -965,7 +965,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final def right[A, B](implicit codec: Codec[B]): Codec.Aux[Right[A, B], codec.Repr] = + implicit final def right[A, B](implicit codec: Codec[B]): Codec.Aux[codec.Repr, Right[A, B]] = codec.imap(Right[A, B](_))(_.value) /** @@ -973,7 +973,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def seq[A]( implicit codec: Codec[A] - ): Codec.Aux[Seq[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], Seq[A]] = Codec .list[A] .imap[Seq[A]](_.toSeq)(_.toList) @@ -984,7 +984,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def set[A]( implicit codec: Codec[A] - ): Codec.Aux[Set[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], Set[A]] = Codec .list[A] .imap(_.toSet)(_.toList) @@ -993,7 +993,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val short: Codec.Aux[Short, java.lang.Integer] = { + implicit final val short: Codec.Aux[java.lang.Integer, Short] = { val min: Int = Short.MinValue.toInt val max: Int = Short.MaxValue.toInt Codec.int @@ -1008,13 +1008,13 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final def some[A](implicit codec: Codec[A]): Codec.Aux[Some[A], codec.Repr] = + implicit final def some[A](implicit codec: Codec[A]): Codec.Aux[codec.Repr, Some[A]] = codec.imap(Some(_))(_.value) /** * @group General */ - implicit final val string: Codec.Aux[String, Utf8] = + implicit final val string: Codec.Aux[Utf8, String] = Codec.instance( Right(SchemaBuilder.builder().stringType()), new Utf8(_).asRight, @@ -1091,7 +1091,7 @@ object Codec extends CodecCompanionCompat { * * @group Create */ - final def union[A](f: AltBuilder[A] => Chain[Alt[A]]): Codec.Aux[A, AnyRef] = { + final def union[A](f: AltBuilder[A] => Chain[Alt[A]]): Codec.Aux[AnyRef, A] = { val alts = f(AltBuilder.instance) val schema = AvroError.catchNonFatal { alts.toList @@ -1166,7 +1166,7 @@ object Codec extends CodecCompanionCompat { /** * @group General */ - implicit final val unit: Codec.Aux[Unit, Null] = + implicit final val unit: Codec.Aux[Null, Unit] = Codec.instanceForTypes( "null", "Unit", @@ -1178,7 +1178,7 @@ object Codec extends CodecCompanionCompat { /** * @group JavaUtil */ - implicit final val uuid: Codec.Aux[UUID, Utf8] = + implicit final val uuid: Codec.Aux[Utf8, UUID] = Codec.instanceForTypes( "Utf8", "UUID", @@ -1199,7 +1199,7 @@ object Codec extends CodecCompanionCompat { */ implicit final def vector[A]( implicit codec: Codec[A] - ): Codec.Aux[Vector[A], java.util.List[codec.Repr]] = + ): Codec.Aux[java.util.List[codec.Repr], Vector[A]] = Codec.instanceForTypes( "Collection", "Vector", @@ -1228,7 +1228,7 @@ object Codec extends CodecCompanionCompat { /** * @group Cats */ - implicit final def codecAuxShow[A, Repr <: AnyRef]: Show[Codec.Aux[A, Repr]] = + implicit final def codecAuxShow[Repr <: AnyRef, A]: Show[Codec.Aux[Repr, A]] = Show.fromToString /** From 753afa8c06f5212ad29c83ab8b3870855a31f7b9 Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Thu, 28 Jan 2021 15:41:51 +0000 Subject: [PATCH 6/8] cleanup --- modules/core/src/main/scala/vulcan/Codec.scala | 4 ++-- modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index ecb49d8b..6134cdc3 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -571,7 +571,7 @@ object Codec extends CodecCompanionCompat { * * @group Create */ - final def instance[A, Repr0 <: AnyRef]( + final def instance[Repr0 <: AnyRef, A]( schema: Either[AvroError, Schema], encode: A => Either[AvroError, Repr0], decode: (Any, Schema) => Either[AvroError, A] @@ -600,7 +600,7 @@ object Codec extends CodecCompanionCompat { } } - private[vulcan] final def instanceForTypes[A, Repr <: AnyRef]( + private[vulcan] final def instanceForTypes[Repr <: AnyRef, A]( expectedValueType: String, decodingTypeName: String, schema: Either[AvroError, Schema], diff --git a/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala b/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala index b54ada79..3078cfa3 100644 --- a/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala +++ b/modules/generic/src/test/scala/vulcan/generic/CodecSpec.scala @@ -61,7 +61,7 @@ final class CodecSpec extends AnyFunSpec with ScalaCheckPropertyChecks with Eith coproductCodec[Int, CNil]( Codec.int, shapeless.Lazy { - Codec.instance[CNil, Null]( + Codec.instance[Null, CNil]( Right(SchemaBuilder.builder().nullType()), _ => Left(AvroError("encode")), (_, _) => Left(AvroError("decode")) From 19329c424ed1a0165b9099746c38b853af8ca24c Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Fri, 29 Jan 2021 10:58:32 +0000 Subject: [PATCH 7/8] refactoring --- modules/core/src/main/scala/vulcan/Codec.scala | 4 +--- modules/generic/src/main/scala/vulcan/generic/package.scala | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index 6134cdc3..50724887 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -753,12 +753,10 @@ object Codec extends CodecCompanionCompat { } .map(_.toMap.asJava), { case (map: java.util.Map[_, _], schema) => - val valueSchema = schema.getValueType() - map.asScala.toList .traverse { case (key: Utf8, value) => - codec.decode(value, valueSchema).tupleLeft(key.toString) + codec.decode(value, schema.getValueType()).tupleLeft(key.toString) case (key, _) => Left(AvroError.decodeUnexpectedMapKey(key)) } diff --git a/modules/generic/src/main/scala/vulcan/generic/package.scala b/modules/generic/src/main/scala/vulcan/generic/package.scala index 29e66e01..5106347c 100644 --- a/modules/generic/src/main/scala/vulcan/generic/package.scala +++ b/modules/generic/src/main/scala/vulcan/generic/package.scala @@ -18,7 +18,7 @@ import vulcan.internal.converters.collection._ import vulcan.internal.tags._ package object generic { - implicit final val cnilCodec: Codec[CNil] = + implicit final val cnilCodec: Codec.Aux[Nothing, CNil] = Codec.instance( Right(Schema.createUnion()), cnil => Left(AvroError.encodeExhaustedAlternatives(cnil, Some("Coproduct"))), @@ -298,7 +298,7 @@ package object generic { symbols: Seq[String], encode: A => String, decode: String => Either[AvroError, A] - )(implicit tag: WeakTypeTag[A]): Codec[A] = + )(implicit tag: WeakTypeTag[A]): Codec.Aux[AnyRef, A] = Codec.enumeration( name = nameFrom(tag), symbols = symbols, @@ -319,7 +319,7 @@ package object generic { size: Int, encode: A => Array[Byte], decode: Array[Byte] => Either[AvroError, A] - )(implicit tag: WeakTypeTag[A]): Codec[A] = + )(implicit tag: WeakTypeTag[A]): Codec.Aux[GenericFixed, A] = Codec.fixed( name = nameFrom(tag), size = size, From d6f974a3eb1b45eeae1cfb8a7105b60597c960b3 Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Fri, 29 Jan 2021 11:09:59 +0000 Subject: [PATCH 8/8] Fix compiler errors in scala 2.12, use more Aux types --- modules/core/src/main/scala-2/vulcan/CodecCompat.scala | 5 +++-- modules/core/src/main/scala/vulcan/Codec.scala | 2 +- modules/generic/src/main/scala/vulcan/generic/package.scala | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/core/src/main/scala-2/vulcan/CodecCompat.scala b/modules/core/src/main/scala-2/vulcan/CodecCompat.scala index d6837d4c..f826a5c4 100644 --- a/modules/core/src/main/scala-2/vulcan/CodecCompat.scala +++ b/modules/core/src/main/scala-2/vulcan/CodecCompat.scala @@ -6,6 +6,7 @@ package vulcan +import org.apache.avro.generic.GenericFixed import scala.reflect.runtime.universe.WeakTypeTag import vulcan.internal.tags._ @@ -20,7 +21,7 @@ private[vulcan] trait CodecCompanionCompat { symbols: Seq[String], encode: A => String, decode: String => Either[AvroError, A] - )(implicit tag: WeakTypeTag[A]): Codec[A] = + )(implicit tag: WeakTypeTag[A]): Codec.Aux[AnyRef, A] = Codec.enumeration( name = nameFrom(tag), symbols = symbols, @@ -39,7 +40,7 @@ private[vulcan] trait CodecCompanionCompat { size: Int, encode: A => Array[Byte], decode: Array[Byte] => Either[AvroError, A] - )(implicit tag: WeakTypeTag[A]): Codec[A] = + )(implicit tag: WeakTypeTag[A]): Codec.Aux[GenericFixed, A] = Codec.fixed( name = nameFrom(tag), size = size, diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index 50724887..c18d0265 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -1097,7 +1097,7 @@ object Codec extends CodecCompanionCompat { .map(schemas => Schema.createUnion(schemas.asJava)) } - Codec.instance( + Codec.instance[AnyRef, A]( schema, a => alts diff --git a/modules/generic/src/main/scala/vulcan/generic/package.scala b/modules/generic/src/main/scala/vulcan/generic/package.scala index 5106347c..b5933c74 100644 --- a/modules/generic/src/main/scala/vulcan/generic/package.scala +++ b/modules/generic/src/main/scala/vulcan/generic/package.scala @@ -221,9 +221,9 @@ package object generic { final def derive[A]: Codec[A] = macro Magnolia.gen[A] - final def dispatch[A](sealedTrait: SealedTrait[Codec, A]): Codec[A] = { + final def dispatch[A](sealedTrait: SealedTrait[Codec, A]): Codec.Aux[AnyRef, A] = { val typeName = sealedTrait.typeName.full - Codec.instance( + Codec.instance[AnyRef, A]( AvroError.catchNonFatal { sealedTrait.subtypes.toList .traverse(_.typeclass.schema)