diff --git a/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroListOfRecordsBenchmark.scala b/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroListOfRecordsBenchmark.scala index 53b26e5533..b7de7d4ce0 100644 --- a/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroListOfRecordsBenchmark.scala +++ b/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroListOfRecordsBenchmark.scala @@ -20,8 +20,7 @@ import org.openjdk.jmh.annotations._ import zio.Chunk import zio.blocks.BaseBenchmark import zio.blocks.schema.Schema -import zio.blocks.schema.avro.{AvroBinaryCodec, AvroFormat} -import zio.schema.codec.AvroCodec +import zio.blocks.schema.avro.{AvroCodec, AvroFormat} import zio.schema.{DeriveSchema, Schema => ZIOSchema} import java.io.ByteArrayOutputStream import com.sksamuel.avro4s.{AvroSchema, AvroInputStream, AvroOutputStream} @@ -78,7 +77,8 @@ object AvroListOfRecordsDomain { implicit val zioSchema: ZIOSchema[Person] = DeriveSchema.gen[Person] - val zioSchemaCodec: AvroCodec.ExtendedBinaryCodec[List[Person]] = AvroCodec.schemaBasedBinaryCodec[List[Person]] + val zioSchemaCodec: zio.schema.codec.AvroCodec.ExtendedBinaryCodec[List[Person]] = + zio.schema.codec.AvroCodec.schemaBasedBinaryCodec[List[Person]] - val zioBlocksCodec: AvroBinaryCodec[List[Person]] = Schema.derived.deriving(AvroFormat.deriver).derive + val zioBlocksCodec: AvroCodec[List[Person]] = Schema.derived.deriving(AvroFormat.deriver).derive } diff --git a/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroNestedRecordsBenchmark.scala b/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroNestedRecordsBenchmark.scala index 89bc61cfa2..d026ec50c3 100644 --- a/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroNestedRecordsBenchmark.scala +++ b/benchmarks/src/main/scala/zio/blocks/schema/avro/AvroNestedRecordsBenchmark.scala @@ -19,7 +19,7 @@ package zio.blocks.schema.avro import org.openjdk.jmh.annotations._ import zio.blocks.BaseBenchmark import zio.blocks.schema.{Schema, SchemaError} -import zio.blocks.schema.avro.{AvroBinaryCodec, AvroFormat} +import zio.blocks.schema.avro.{AvroCodec, AvroFormat} import scala.compiletime.uninitialized class AvroNestedRecordsBenchmark extends BaseBenchmark { @@ -55,5 +55,5 @@ class AvroNestedRecordsBenchmark extends BaseBenchmark { object AvroNestedRecordsBenchmark { case class Nested(value: Int, next: Option[Nested]) - val zioBlocksCodec: AvroBinaryCodec[Nested] = Schema.derived.deriving(AvroFormat.deriver).derive + val zioBlocksCodec: AvroCodec[Nested] = Schema.derived.deriving(AvroFormat.deriver).derive } diff --git a/docs/reference/codec.md b/docs/reference/codec.md index a4a52bf0ce..c7f4fec3a9 100644 --- a/docs/reference/codec.md +++ b/docs/reference/codec.md @@ -77,7 +77,7 @@ The codec system in ZIO Blocks is organized as a layered hierarchy: Codec[DecodeInput, EncodeOutput, Value] ├── BinaryCodec[A] = Codec[ByteBuffer, ByteBuffer, A] (ByteBuffer ↔ A) │ ├── JsonCodec[A] -│ ├── AvroBinaryCodec[A] +│ ├── AvroCodec[A] │ ├── ToonBinaryCodec[A] │ ├── ThriftBinaryCodec[A] │ └── MessagePackBinaryCodec[A] diff --git a/docs/reference/formats.md b/docs/reference/formats.md index d57a71c825..c685c16536 100644 --- a/docs/reference/formats.md +++ b/docs/reference/formats.md @@ -49,7 +49,7 @@ Here's a summary of the formats currently supported by ZIO Blocks. Each format p | `JsonFormat` | `JsonCodec[A]` | `application/json` | `zio-blocks-schema` | | `ToonFormat` | `ToonBinaryCodec[A]` | `text/toon` | `zio-blocks-schema-toon` | | `MessagePackFormat` | `MessagePackBinaryCodec[A]` | `application/msgpack` | `zio-blocks-schema-messagepack` | -| `AvroFormat` | `AvroBinaryCodec[A]` | `application/avro` | `zio-blocks-schema-avro` | +| `AvroFormat` | `AvroCodec[A]` | `application/avro` | `zio-blocks-schema-avro` | | `ThriftFormat` | `ThriftBinaryCodec[A]` | `application/thrift` | `zio-blocks-schema-thrift` | ## Defining a Custom Format @@ -162,7 +162,7 @@ val decoded: Either[SchemaError, Person] = codec.decode(bytes) ### Avro Schema Generation -Each `AvroBinaryCodec` exposes an `avroSchema` property containing the Apache Avro schema: +Each `AvroCodec` exposes an `avroSchema` property containing the Apache Avro schema: ```scala mdoc:compile-only import zio.blocks.schema._ diff --git a/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroBinaryCodec.scala b/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroCodec.scala similarity index 84% rename from schema-avro/src/main/scala/zio/blocks/schema/avro/AvroBinaryCodec.scala rename to schema-avro/src/main/scala/zio/blocks/schema/avro/AvroCodec.scala index 6c3302945e..b72bd2f81c 100644 --- a/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroBinaryCodec.scala +++ b/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroCodec.scala @@ -20,7 +20,6 @@ import org.apache.avro.io.{BinaryDecoder, BinaryEncoder, DecoderFactory, DirectB import org.apache.avro.{Schema => AvroSchema} import zio.blocks.schema.SchemaError.ExpectationMismatch import zio.blocks.schema.{DynamicOptic, SchemaError} -import zio.blocks.schema.binding.RegisterOffset import zio.blocks.schema.codec.BinaryCodec import java.io.OutputStream import java.math.{BigInteger, MathContext} @@ -30,38 +29,25 @@ import java.util.{Currency, UUID} import scala.collection.immutable.ArraySeq import scala.util.control.NonFatal -abstract class AvroBinaryCodec[A](val valueType: Int = AvroBinaryCodec.objectType) extends BinaryCodec[A] { - val valueOffset: RegisterOffset.RegisterOffset = valueType match { - case AvroBinaryCodec.objectType => RegisterOffset(objects = 1) - case AvroBinaryCodec.booleanType => RegisterOffset(booleans = 1) - case AvroBinaryCodec.byteType => RegisterOffset(bytes = 1) - case AvroBinaryCodec.charType => RegisterOffset(chars = 1) - case AvroBinaryCodec.shortType => RegisterOffset(shorts = 1) - case AvroBinaryCodec.floatType => RegisterOffset(floats = 1) - case AvroBinaryCodec.intType => RegisterOffset(ints = 1) - case AvroBinaryCodec.doubleType => RegisterOffset(doubles = 1) - case AvroBinaryCodec.longType => RegisterOffset(longs = 1) - case _ => RegisterOffset.Zero - } - +abstract class AvroCodec[A] extends BinaryCodec[A] { def avroSchema: AvroSchema - def decodeError(expectation: String): Nothing = throw new AvroBinaryCodecError(Nil, expectation) + def decodeError(expectation: String): Nothing = throw new AvroCodecError(Nil, expectation) def decodeError(span: DynamicOptic.Node, error: Throwable): Nothing = error match { - case e: AvroBinaryCodecError => + case e: AvroCodecError => e.spans = new ::(span, e.spans) throw e case _ => - throw new AvroBinaryCodecError(new ::(span, Nil), getMessage(error)) + throw new AvroCodecError(new ::(span, Nil), getMessage(error)) } def decodeError(span1: DynamicOptic.Node, span2: DynamicOptic.Node, error: Throwable): Nothing = error match { - case e: AvroBinaryCodecError => + case e: AvroCodecError => e.spans = new ::(span1, new ::(span2, e.spans)) throw e case _ => - throw new AvroBinaryCodecError(new ::(span1, new ::(span2, Nil)), getMessage(error)) + throw new AvroCodecError(new ::(span1, new ::(span2, Nil)), getMessage(error)) } def decodeUnsafe(decoder: BinaryDecoder): A @@ -113,7 +99,7 @@ abstract class AvroBinaryCodec[A](val valueType: Int = AvroBinaryCodec.objectTyp private[this] def toError(error: Throwable): SchemaError = new SchemaError( new ::( error match { - case e: AvroBinaryCodecError => + case e: AvroCodecError => var list = e.spans val array = new Array[DynamicOptic.Node](list.size) var idx = 0 @@ -138,21 +124,10 @@ abstract class AvroBinaryCodec[A](val valueType: Int = AvroBinaryCodec.objectTyp } } -object AvroBinaryCodec { - val objectType = 0 - val booleanType = 1 - val byteType = 2 - val charType = 3 - val shortType = 4 - val floatType = 5 - val intType = 6 - val doubleType = 7 - val longType = 8 - val unitType = 9 - +object AvroCodec { val maxCollectionSize: Int = Integer.MAX_VALUE - 8 - val unitCodec: AvroBinaryCodec[Unit] = new AvroBinaryCodec[Unit](AvroBinaryCodec.unitType) { + val unitCodec: AvroCodec[Unit] = new AvroCodec[Unit] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.NULL) def decodeUnsafe(decoder: BinaryDecoder): Unit = () @@ -160,7 +135,7 @@ object AvroBinaryCodec { def encode(value: Unit, encoder: BinaryEncoder): Unit = () } - val booleanCodec: AvroBinaryCodec[Boolean] = new AvroBinaryCodec[Boolean](AvroBinaryCodec.booleanType) { + val booleanCodec: AvroCodec[Boolean] = new AvroCodec[Boolean] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.BOOLEAN) def decodeUnsafe(decoder: BinaryDecoder): Boolean = decoder.readBoolean() @@ -168,7 +143,7 @@ object AvroBinaryCodec { def encode(value: Boolean, encoder: BinaryEncoder): Unit = encoder.writeBoolean(value) } - val byteCodec: AvroBinaryCodec[Byte] = new AvroBinaryCodec[Byte](AvroBinaryCodec.byteType) { + val byteCodec: AvroCodec[Byte] = new AvroCodec[Byte] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.INT) def decodeUnsafe(decoder: BinaryDecoder): Byte = { @@ -180,7 +155,7 @@ object AvroBinaryCodec { def encode(value: Byte, encoder: BinaryEncoder): Unit = encoder.writeInt(value) } - val shortCodec: AvroBinaryCodec[Short] = new AvroBinaryCodec[Short](AvroBinaryCodec.shortType) { + val shortCodec: AvroCodec[Short] = new AvroCodec[Short] { val avroSchema: AvroSchema = byteCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): Short = { @@ -192,7 +167,7 @@ object AvroBinaryCodec { def encode(value: Short, encoder: BinaryEncoder): Unit = encoder.writeInt(value) } - val intCodec: AvroBinaryCodec[Int] = new AvroBinaryCodec[Int](AvroBinaryCodec.intType) { + val intCodec: AvroCodec[Int] = new AvroCodec[Int] { val avroSchema: AvroSchema = shortCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): Int = decoder.readInt() @@ -200,7 +175,7 @@ object AvroBinaryCodec { def encode(value: Int, encoder: BinaryEncoder): Unit = encoder.writeInt(value) } - val longCodec: AvroBinaryCodec[Long] = new AvroBinaryCodec[Long](AvroBinaryCodec.longType) { + val longCodec: AvroCodec[Long] = new AvroCodec[Long] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.LONG) def decodeUnsafe(decoder: BinaryDecoder): Long = decoder.readLong() @@ -208,7 +183,7 @@ object AvroBinaryCodec { def encode(value: Long, encoder: BinaryEncoder): Unit = encoder.writeLong(value) } - val floatCodec: AvroBinaryCodec[Float] = new AvroBinaryCodec[Float](AvroBinaryCodec.floatType) { + val floatCodec: AvroCodec[Float] = new AvroCodec[Float] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.FLOAT) def decodeUnsafe(decoder: BinaryDecoder): Float = decoder.readFloat() @@ -216,7 +191,7 @@ object AvroBinaryCodec { def encode(value: Float, encoder: BinaryEncoder): Unit = encoder.writeFloat(value) } - val doubleCodec: AvroBinaryCodec[Double] = new AvroBinaryCodec[Double](AvroBinaryCodec.doubleType) { + val doubleCodec: AvroCodec[Double] = new AvroCodec[Double] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.DOUBLE) def decodeUnsafe(decoder: BinaryDecoder): Double = decoder.readDouble() @@ -224,7 +199,7 @@ object AvroBinaryCodec { def encode(value: Double, encoder: BinaryEncoder): Unit = encoder.writeDouble(value) } - val charCodec: AvroBinaryCodec[Char] = new AvroBinaryCodec[Char](AvroBinaryCodec.charType) { + val charCodec: AvroCodec[Char] = new AvroCodec[Char] { val avroSchema: AvroSchema = intCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): Char = { @@ -236,7 +211,7 @@ object AvroBinaryCodec { def encode(value: Char, encoder: BinaryEncoder): Unit = encoder.writeInt(value) } - val stringCodec: AvroBinaryCodec[String] = new AvroBinaryCodec[String]() { + val stringCodec: AvroCodec[String] = new AvroCodec[String] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.STRING) def decodeUnsafe(decoder: BinaryDecoder): String = decoder.readString() @@ -244,7 +219,7 @@ object AvroBinaryCodec { def encode(value: String, encoder: BinaryEncoder): Unit = encoder.writeString(value) } - val bigIntCodec: AvroBinaryCodec[BigInt] = new AvroBinaryCodec[BigInt]() { + val bigIntCodec: AvroCodec[BigInt] = new AvroCodec[BigInt] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.BYTES) def decodeUnsafe(decoder: BinaryDecoder): BigInt = BigInt(decoder.readBytes(null).array()) @@ -252,7 +227,7 @@ object AvroBinaryCodec { def encode(value: BigInt, encoder: BinaryEncoder): Unit = encoder.writeBytes(value.toByteArray) } - val bigDecimalCodec: AvroBinaryCodec[BigDecimal] = new AvroBinaryCodec[BigDecimal]() { + val bigDecimalCodec: AvroCodec[BigDecimal] = new AvroCodec[BigDecimal] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](4) @@ -282,7 +257,7 @@ object AvroBinaryCodec { } } - val dayOfWeekCodec: AvroBinaryCodec[DayOfWeek] = new AvroBinaryCodec[DayOfWeek]() { + val dayOfWeekCodec: AvroCodec[DayOfWeek] = new AvroCodec[DayOfWeek] { val avroSchema: AvroSchema = intCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): DayOfWeek = DayOfWeek.of(decoder.readInt()) @@ -290,7 +265,7 @@ object AvroBinaryCodec { def encode(value: DayOfWeek, encoder: BinaryEncoder): Unit = encoder.writeInt(value.getValue) } - val durationCodec: AvroBinaryCodec[Duration] = new AvroBinaryCodec[Duration]() { + val durationCodec: AvroCodec[Duration] = new AvroCodec[Duration] { val avroSchema: AvroSchema = { val fields = new java.util.ArrayList[AvroSchema.Field](2) fields.add(new AvroSchema.Field("seconds", longCodec.avroSchema)) @@ -306,7 +281,7 @@ object AvroBinaryCodec { } } - val instantCodec: AvroBinaryCodec[Instant] = new AvroBinaryCodec[Instant]() { + val instantCodec: AvroCodec[Instant] = new AvroCodec[Instant] { val avroSchema: AvroSchema = { val fields = new java.util.ArrayList[AvroSchema.Field](2) fields.add(new AvroSchema.Field("epochSecond", longCodec.avroSchema)) @@ -322,7 +297,7 @@ object AvroBinaryCodec { } } - val localDateCodec: AvroBinaryCodec[LocalDate] = new AvroBinaryCodec[LocalDate]() { + val localDateCodec: AvroCodec[LocalDate] = new AvroCodec[LocalDate] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](3) @@ -342,7 +317,7 @@ object AvroBinaryCodec { } } - val localDateTimeCodec: AvroBinaryCodec[LocalDateTime] = new AvroBinaryCodec[LocalDateTime]() { + val localDateTimeCodec: AvroCodec[LocalDateTime] = new AvroCodec[LocalDateTime] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](7) @@ -379,7 +354,7 @@ object AvroBinaryCodec { } } - val localTimeCodec: AvroBinaryCodec[LocalTime] = new AvroBinaryCodec[LocalTime]() { + val localTimeCodec: AvroCodec[LocalTime] = new AvroCodec[LocalTime] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](4) @@ -401,7 +376,7 @@ object AvroBinaryCodec { } } - val monthCodec: AvroBinaryCodec[Month] = new AvroBinaryCodec[Month]() { + val monthCodec: AvroCodec[Month] = new AvroCodec[Month] { val avroSchema: AvroSchema = intCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): Month = Month.of(decoder.readInt()) @@ -409,7 +384,7 @@ object AvroBinaryCodec { def encode(value: Month, encoder: BinaryEncoder): Unit = encoder.writeInt(value.getValue) } - val monthDayCodec: AvroBinaryCodec[MonthDay] = new AvroBinaryCodec[MonthDay]() { + val monthDayCodec: AvroCodec[MonthDay] = new AvroCodec[MonthDay] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](2) @@ -426,7 +401,7 @@ object AvroBinaryCodec { } } - val offsetDateTimeCodec: AvroBinaryCodec[OffsetDateTime] = new AvroBinaryCodec[OffsetDateTime]() { + val offsetDateTimeCodec: AvroCodec[OffsetDateTime] = new AvroCodec[OffsetDateTime] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](8) @@ -465,7 +440,7 @@ object AvroBinaryCodec { } } - val offsetTimeCodec: AvroBinaryCodec[OffsetTime] = new AvroBinaryCodec[OffsetTime]() { + val offsetTimeCodec: AvroCodec[OffsetTime] = new AvroCodec[OffsetTime] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](5) @@ -495,7 +470,7 @@ object AvroBinaryCodec { } } - val periodCodec: AvroBinaryCodec[Period] = new AvroBinaryCodec[Period]() { + val periodCodec: AvroCodec[Period] = new AvroCodec[Period] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](3) @@ -515,7 +490,7 @@ object AvroBinaryCodec { } } - val yearCodec: AvroBinaryCodec[Year] = new AvroBinaryCodec[Year]() { + val yearCodec: AvroCodec[Year] = new AvroCodec[Year] { val avroSchema: AvroSchema = intCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): Year = Year.of(decoder.readInt()) @@ -523,7 +498,7 @@ object AvroBinaryCodec { def encode(value: Year, encoder: BinaryEncoder): Unit = encoder.writeInt(value.getValue) } - val yearMonthCodec: AvroBinaryCodec[YearMonth] = new AvroBinaryCodec[YearMonth]() { + val yearMonthCodec: AvroCodec[YearMonth] = new AvroCodec[YearMonth] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](2) @@ -540,7 +515,7 @@ object AvroBinaryCodec { } } - val zoneIdCodec: AvroBinaryCodec[ZoneId] = new AvroBinaryCodec[ZoneId]() { + val zoneIdCodec: AvroCodec[ZoneId] = new AvroCodec[ZoneId] { val avroSchema: AvroSchema = stringCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): ZoneId = ZoneId.of(decoder.readString()) @@ -548,7 +523,7 @@ object AvroBinaryCodec { def encode(value: ZoneId, encoder: BinaryEncoder): Unit = encoder.writeString(value.toString) } - val zoneOffsetCodec: AvroBinaryCodec[ZoneOffset] = new AvroBinaryCodec[ZoneOffset]() { + val zoneOffsetCodec: AvroCodec[ZoneOffset] = new AvroCodec[ZoneOffset] { val avroSchema: AvroSchema = intCodec.avroSchema def decodeUnsafe(decoder: BinaryDecoder): ZoneOffset = @@ -558,7 +533,7 @@ object AvroBinaryCodec { encoder.writeInt(value.getTotalSeconds) } - val zonedDateTimeCodec: AvroBinaryCodec[ZonedDateTime] = new AvroBinaryCodec[ZonedDateTime]() { + val zonedDateTimeCodec: AvroCodec[ZonedDateTime] = new AvroCodec[ZonedDateTime] { val avroSchema: AvroSchema = { val intAvroSchema = intCodec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](9) @@ -602,7 +577,7 @@ object AvroBinaryCodec { } } - val currencyCodec: AvroBinaryCodec[Currency] = new AvroBinaryCodec[java.util.Currency]() { + val currencyCodec: AvroCodec[Currency] = new AvroCodec[java.util.Currency] { val avroSchema: AvroSchema = AvroSchema.createFixed("Currency", null, "java.util", 3) def decodeUnsafe(decoder: BinaryDecoder): java.util.Currency = { @@ -617,7 +592,7 @@ object AvroBinaryCodec { } } - val uuidCodec: AvroBinaryCodec[UUID] = new AvroBinaryCodec[java.util.UUID]() { + val uuidCodec: AvroCodec[UUID] = new AvroCodec[java.util.UUID] { val avroSchema: AvroSchema = AvroSchema.createFixed("UUID", null, "java.util", 16) def decodeUnsafe(decoder: BinaryDecoder): java.util.UUID = { @@ -676,7 +651,7 @@ object AvroBinaryCodec { ): AvroSchema = AvroSchema.createRecord(name, null, namespace, false, fields) } -private class AvroBinaryCodecError(var spans: List[DynamicOptic.Node], message: String) +private class AvroCodecError(var spans: List[DynamicOptic.Node], message: String) extends Throwable(message, null, false, false) { override def getMessage: String = message } diff --git a/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroFormat.scala b/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroFormat.scala index 17e8122579..99793f09bb 100644 --- a/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroFormat.scala +++ b/schema-avro/src/main/scala/zio/blocks/schema/avro/AvroFormat.scala @@ -26,13 +26,14 @@ import zio.blocks.chunk.ChunkBuilder import zio.blocks.schema.codec.BinaryFormat import zio.blocks.schema.derive.{BindingInstance, Deriver, InstanceOverride} import zio.blocks.typeid.TypeId +import scala.annotation.switch import scala.reflect.ClassTag import scala.util.control.NonFatal object AvroFormat extends BinaryFormat( "application/avro", - new Deriver[AvroBinaryCodec] { + new Deriver[AvroCodec] { override def derivePrimitive[A]( primitiveType: PrimitiveType[A], typeId: TypeId[A], @@ -41,42 +42,42 @@ object AvroFormat modifiers: Seq[Modifier.Reflect], defaultValue: Option[A], examples: Seq[A] - ): Lazy[AvroBinaryCodec[A]] = { + ): Lazy[AvroCodec[A]] = { if (binding.isInstanceOf[Binding[?, ?]]) { Lazy(primitiveType match { - case _: PrimitiveType.Unit.type => AvroBinaryCodec.unitCodec - case _: PrimitiveType.Boolean => AvroBinaryCodec.booleanCodec - case _: PrimitiveType.Byte => AvroBinaryCodec.byteCodec - case _: PrimitiveType.Short => AvroBinaryCodec.shortCodec - case _: PrimitiveType.Int => AvroBinaryCodec.intCodec - case _: PrimitiveType.Long => AvroBinaryCodec.longCodec - case _: PrimitiveType.Float => AvroBinaryCodec.floatCodec - case _: PrimitiveType.Double => AvroBinaryCodec.doubleCodec - case _: PrimitiveType.Char => AvroBinaryCodec.charCodec - case _: PrimitiveType.String => AvroBinaryCodec.stringCodec - case _: PrimitiveType.BigInt => AvroBinaryCodec.bigIntCodec - case _: PrimitiveType.BigDecimal => AvroBinaryCodec.bigDecimalCodec - case _: PrimitiveType.DayOfWeek => AvroBinaryCodec.dayOfWeekCodec - case _: PrimitiveType.Duration => AvroBinaryCodec.durationCodec - case _: PrimitiveType.Instant => AvroBinaryCodec.instantCodec - case _: PrimitiveType.LocalDate => AvroBinaryCodec.localDateCodec - case _: PrimitiveType.LocalDateTime => AvroBinaryCodec.localDateTimeCodec - case _: PrimitiveType.LocalTime => AvroBinaryCodec.localTimeCodec - case _: PrimitiveType.Month => AvroBinaryCodec.monthCodec - case _: PrimitiveType.MonthDay => AvroBinaryCodec.monthDayCodec - case _: PrimitiveType.OffsetDateTime => AvroBinaryCodec.offsetDateTimeCodec - case _: PrimitiveType.OffsetTime => AvroBinaryCodec.offsetTimeCodec - case _: PrimitiveType.Period => AvroBinaryCodec.periodCodec - case _: PrimitiveType.Year => AvroBinaryCodec.yearCodec - case _: PrimitiveType.YearMonth => AvroBinaryCodec.yearMonthCodec - case _: PrimitiveType.ZoneId => AvroBinaryCodec.zoneIdCodec - case _: PrimitiveType.ZoneOffset => AvroBinaryCodec.zoneOffsetCodec - case _: PrimitiveType.ZonedDateTime => AvroBinaryCodec.zonedDateTimeCodec - case _: PrimitiveType.Currency => AvroBinaryCodec.currencyCodec - case _: PrimitiveType.UUID => AvroBinaryCodec.uuidCodec + case _: PrimitiveType.Unit.type => AvroCodec.unitCodec + case _: PrimitiveType.Boolean => AvroCodec.booleanCodec + case _: PrimitiveType.Byte => AvroCodec.byteCodec + case _: PrimitiveType.Short => AvroCodec.shortCodec + case _: PrimitiveType.Int => AvroCodec.intCodec + case _: PrimitiveType.Long => AvroCodec.longCodec + case _: PrimitiveType.Float => AvroCodec.floatCodec + case _: PrimitiveType.Double => AvroCodec.doubleCodec + case _: PrimitiveType.Char => AvroCodec.charCodec + case _: PrimitiveType.String => AvroCodec.stringCodec + case _: PrimitiveType.BigInt => AvroCodec.bigIntCodec + case _: PrimitiveType.BigDecimal => AvroCodec.bigDecimalCodec + case _: PrimitiveType.DayOfWeek => AvroCodec.dayOfWeekCodec + case _: PrimitiveType.Duration => AvroCodec.durationCodec + case _: PrimitiveType.Instant => AvroCodec.instantCodec + case _: PrimitiveType.LocalDate => AvroCodec.localDateCodec + case _: PrimitiveType.LocalDateTime => AvroCodec.localDateTimeCodec + case _: PrimitiveType.LocalTime => AvroCodec.localTimeCodec + case _: PrimitiveType.Month => AvroCodec.monthCodec + case _: PrimitiveType.MonthDay => AvroCodec.monthDayCodec + case _: PrimitiveType.OffsetDateTime => AvroCodec.offsetDateTimeCodec + case _: PrimitiveType.OffsetTime => AvroCodec.offsetTimeCodec + case _: PrimitiveType.Period => AvroCodec.periodCodec + case _: PrimitiveType.Year => AvroCodec.yearCodec + case _: PrimitiveType.YearMonth => AvroCodec.yearMonthCodec + case _: PrimitiveType.ZoneId => AvroCodec.zoneIdCodec + case _: PrimitiveType.ZoneOffset => AvroCodec.zoneOffsetCodec + case _: PrimitiveType.ZonedDateTime => AvroCodec.zonedDateTimeCodec + case _: PrimitiveType.Currency => AvroCodec.currencyCodec + case _: PrimitiveType.UUID => AvroCodec.uuidCodec }) } else binding.asInstanceOf[BindingInstance[TC, ?, A]].instance - }.asInstanceOf[Lazy[AvroBinaryCodec[A]]] + }.asInstanceOf[Lazy[AvroCodec[A]]] override def deriveRecord[F[_, _], A]( fields: IndexedSeq[Term[F, A, ?]], @@ -86,115 +87,98 @@ object AvroFormat modifiers: Seq[Modifier.Reflect], defaultValue: Option[A], examples: Seq[A] - )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroBinaryCodec[A]] = { + )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroCodec[A]] = { if (binding.isInstanceOf[Binding[?, ?]]) { - val recordBinding = binding.asInstanceOf[Binding.Record[A]] - val isRecursive = fields.exists(_.value.isInstanceOf[Reflect.Deferred[F, ?]]) - var codecsWithAvroSchema = + val recordBinding = binding.asInstanceOf[Binding.Record[A]] + val isRecursive = fields.exists(_.value.isInstanceOf[Reflect.Deferred[F, ?]]) + var fieldInfosWithAvroSchema = if (isRecursive) recursiveRecordCache.get.get(typeId) else null var offset = 0L - if (codecsWithAvroSchema eq null) { + if (fieldInfosWithAvroSchema eq null) { val namespace = typeId.owner.asString val avroSchema = createAvroRecord(namespace, typeId.name) val len = fields.length - val codecs = new Array[AvroBinaryCodec[?]](len) - codecsWithAvroSchema = (codecs, avroSchema) - if (isRecursive) recursiveRecordCache.get.put(typeId, codecsWithAvroSchema) + val fieldInfos = new Array[FieldInfo](len) + fieldInfosWithAvroSchema = (fieldInfos, avroSchema) + if (isRecursive) recursiveRecordCache.get.put(typeId, fieldInfosWithAvroSchema) val avroSchemaFields = new java.util.ArrayList[AvroSchema.Field](len) var idx = 0 while (idx < len) { - val field = fields(idx) - val codec = D.instance(field.value.metadata).force.asInstanceOf[AvroBinaryCodec[?]] - codecs(idx) = codec + val field = fields(idx) + val fieldReflect = field.value + val codec = D.instance(fieldReflect.metadata).force.asInstanceOf[AvroCodec[?]] + fieldInfos(idx) = new FieldInfo(codec, typeTag(fieldReflect), offset) avroSchemaFields.add(new AvroSchema.Field(field.name, codec.avroSchema)) - offset = RegisterOffset.add(codec.valueOffset, offset) + offset = RegisterOffset.add(registerOffset(fieldReflect), offset) idx += 1 } avroSchema.setFields(avroSchemaFields) } - Lazy(new AvroBinaryCodec[A]() { + Lazy(new AvroCodec[A]() { private[this] val deconstructor = recordBinding.deconstructor private[this] val constructor = recordBinding.constructor private[this] val usedRegisters = offset - private[this] val fieldCodecs = codecsWithAvroSchema._1 + private[this] val fieldInfos = fieldInfosWithAvroSchema._1 - val avroSchema: AvroSchema = codecsWithAvroSchema._2 + val avroSchema: AvroSchema = fieldInfosWithAvroSchema._2 def decodeUnsafe(decoder: BinaryDecoder): A = { - val regs = Registers(usedRegisters) - var offset = 0L - val len = fieldCodecs.length - var idx = 0 + val regs = Registers(usedRegisters) + val len = fieldInfos.length + var idx = 0 try { while (idx < len) { - val codec = fieldCodecs(idx) - codec.valueType match { - case AvroBinaryCodec.objectType => - regs.setObject(offset, codec.asInstanceOf[AvroBinaryCodec[AnyRef]].decodeUnsafe(decoder)) - case AvroBinaryCodec.intType => - regs.setInt(offset, codec.asInstanceOf[AvroBinaryCodec[Int]].decodeUnsafe(decoder)) - case AvroBinaryCodec.longType => - regs.setLong(offset, codec.asInstanceOf[AvroBinaryCodec[Long]].decodeUnsafe(decoder)) - case AvroBinaryCodec.floatType => - regs.setFloat(offset, codec.asInstanceOf[AvroBinaryCodec[Float]].decodeUnsafe(decoder)) - case AvroBinaryCodec.doubleType => - regs.setDouble(offset, codec.asInstanceOf[AvroBinaryCodec[Double]].decodeUnsafe(decoder)) - case AvroBinaryCodec.booleanType => - regs.setBoolean(offset, codec.asInstanceOf[AvroBinaryCodec[Boolean]].decodeUnsafe(decoder)) - case AvroBinaryCodec.byteType => - regs.setByte(offset, codec.asInstanceOf[AvroBinaryCodec[Byte]].decodeUnsafe(decoder)) - case AvroBinaryCodec.charType => - regs.setChar(offset, codec.asInstanceOf[AvroBinaryCodec[Char]].decodeUnsafe(decoder)) - case AvroBinaryCodec.shortType => - regs.setShort(offset, codec.asInstanceOf[AvroBinaryCodec[Short]].decodeUnsafe(decoder)) - case _ => codec.asInstanceOf[AvroBinaryCodec[Unit]].decodeUnsafe(decoder) + val fieldInfo = fieldInfos(idx) + val codec = fieldInfo.codec + val offset = fieldInfo.offset + (fieldInfo.typeTag: @switch) match { + case 0 => regs.setObject(offset, codec.asInstanceOf[AvroCodec[AnyRef]].decodeUnsafe(decoder)) + case 1 => regs.setInt(offset, codec.asInstanceOf[AvroCodec[Int]].decodeUnsafe(decoder)) + case 2 => regs.setLong(offset, codec.asInstanceOf[AvroCodec[Long]].decodeUnsafe(decoder)) + case 3 => regs.setFloat(offset, codec.asInstanceOf[AvroCodec[Float]].decodeUnsafe(decoder)) + case 4 => regs.setDouble(offset, codec.asInstanceOf[AvroCodec[Double]].decodeUnsafe(decoder)) + case 5 => regs.setBoolean(offset, codec.asInstanceOf[AvroCodec[Boolean]].decodeUnsafe(decoder)) + case 6 => regs.setByte(offset, codec.asInstanceOf[AvroCodec[Byte]].decodeUnsafe(decoder)) + case 7 => regs.setChar(offset, codec.asInstanceOf[AvroCodec[Char]].decodeUnsafe(decoder)) + case 8 => regs.setShort(offset, codec.asInstanceOf[AvroCodec[Short]].decodeUnsafe(decoder)) + case _ => codec.asInstanceOf[AvroCodec[Unit]].decodeUnsafe(decoder) } - offset += codec.valueOffset idx += 1 } - constructor.construct(regs, 0) + constructor.construct(regs, 0L) } catch { case error if NonFatal(error) => decodeError(new DynamicOptic.Node.Field(fields(idx).name), error) } } def encode(value: A, encoder: BinaryEncoder): Unit = { - val regs = Registers(usedRegisters) - var offset = 0L - deconstructor.deconstruct(regs, offset, value) - val len = fieldCodecs.length + val regs = Registers(usedRegisters) + deconstructor.deconstruct(regs, 0L, value) + val len = fieldInfos.length var idx = 0 while (idx < len) { - val codec = fieldCodecs(idx) - codec.valueType match { - case AvroBinaryCodec.objectType => - codec.asInstanceOf[AvroBinaryCodec[AnyRef]].encode(regs.getObject(offset), encoder) - case AvroBinaryCodec.intType => - codec.asInstanceOf[AvroBinaryCodec[Int]].encode(regs.getInt(offset), encoder) - case AvroBinaryCodec.longType => - codec.asInstanceOf[AvroBinaryCodec[Long]].encode(regs.getLong(offset), encoder) - case AvroBinaryCodec.floatType => - codec.asInstanceOf[AvroBinaryCodec[Float]].encode(regs.getFloat(offset), encoder) - case AvroBinaryCodec.doubleType => - codec.asInstanceOf[AvroBinaryCodec[Double]].encode(regs.getDouble(offset), encoder) - case AvroBinaryCodec.booleanType => - codec.asInstanceOf[AvroBinaryCodec[Boolean]].encode(regs.getBoolean(offset), encoder) - case AvroBinaryCodec.byteType => - codec.asInstanceOf[AvroBinaryCodec[Byte]].encode(regs.getByte(offset), encoder) - case AvroBinaryCodec.charType => - codec.asInstanceOf[AvroBinaryCodec[Char]].encode(regs.getChar(offset), encoder) - case AvroBinaryCodec.shortType => - codec.asInstanceOf[AvroBinaryCodec[Short]].encode(regs.getShort(offset), encoder) - case _ => codec.asInstanceOf[AvroBinaryCodec[Unit]].encode((), encoder) + val fieldInfo = fieldInfos(idx) + val codec = fieldInfo.codec + val offset = fieldInfo.offset + (fieldInfo.typeTag: @switch) match { + case 0 => codec.asInstanceOf[AvroCodec[AnyRef]].encode(regs.getObject(offset), encoder) + case 1 => codec.asInstanceOf[AvroCodec[Int]].encode(regs.getInt(offset), encoder) + case 2 => codec.asInstanceOf[AvroCodec[Long]].encode(regs.getLong(offset), encoder) + case 3 => codec.asInstanceOf[AvroCodec[Float]].encode(regs.getFloat(offset), encoder) + case 4 => codec.asInstanceOf[AvroCodec[Double]].encode(regs.getDouble(offset), encoder) + case 5 => codec.asInstanceOf[AvroCodec[Boolean]].encode(regs.getBoolean(offset), encoder) + case 6 => codec.asInstanceOf[AvroCodec[Byte]].encode(regs.getByte(offset), encoder) + case 7 => codec.asInstanceOf[AvroCodec[Char]].encode(regs.getChar(offset), encoder) + case 8 => codec.asInstanceOf[AvroCodec[Short]].encode(regs.getShort(offset), encoder) + case _ => codec.asInstanceOf[AvroCodec[Unit]].encode((), encoder) } - offset += codec.valueOffset idx += 1 } } }) } else binding.asInstanceOf[BindingInstance[TC, ?, ?]].instance - }.asInstanceOf[Lazy[AvroBinaryCodec[A]]] + }.asInstanceOf[Lazy[AvroCodec[A]]] override def deriveVariant[F[_, _], A]( cases: IndexedSeq[Term[F, A, ?]], @@ -204,17 +188,17 @@ object AvroFormat modifiers: Seq[Modifier.Reflect], defaultValue: Option[A], examples: Seq[A] - )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroBinaryCodec[A]] = { + )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroCodec[A]] = { if (binding.isInstanceOf[Binding[?, ?]]) { val variantBinding = binding.asInstanceOf[Binding.Variant[A]] val len = cases.length - val codecs = new Array[AvroBinaryCodec[?]](len) + val codecs = new Array[AvroCodec[?]](len) var idx = 0 while (idx < len) { - codecs(idx) = D.instance(cases(idx).value.metadata).force.asInstanceOf[AvroBinaryCodec[A]] + codecs(idx) = D.instance(cases(idx).value.metadata).force.asInstanceOf[AvroCodec[A]] idx += 1 } - Lazy(new AvroBinaryCodec[A]() { + Lazy(new AvroCodec[A]() { private[this] val discriminator = variantBinding.discriminator private[this] val caseCodecs = codecs @@ -232,7 +216,7 @@ object AvroFormat def decodeUnsafe(decoder: BinaryDecoder): A = { val idx = decoder.readInt() if (idx >= 0 && idx < caseCodecs.length) { - try caseCodecs(idx).asInstanceOf[AvroBinaryCodec[A]].decodeUnsafe(decoder) + try caseCodecs(idx).asInstanceOf[AvroCodec[A]].decodeUnsafe(decoder) catch { case error if NonFatal(error) => decodeError(new DynamicOptic.Node.Case(cases(idx).name), error) } @@ -242,11 +226,11 @@ object AvroFormat def encode(value: A, encoder: BinaryEncoder): Unit = { val idx = discriminator.discriminate(value) encoder.writeInt(idx) - caseCodecs(idx).asInstanceOf[AvroBinaryCodec[A]].encode(value, encoder) + caseCodecs(idx).asInstanceOf[AvroCodec[A]].encode(value, encoder) } }) } else binding.asInstanceOf[BindingInstance[TC, ?, A]].instance - }.asInstanceOf[Lazy[AvroBinaryCodec[A]]] + }.asInstanceOf[Lazy[AvroCodec[A]]] override def deriveSequence[F[_, _], C[_], A]( element: Reflect[F, A], @@ -256,16 +240,16 @@ object AvroFormat modifiers: Seq[Modifier.Reflect], defaultValue: Option[C[A]], examples: Seq[C[A]] - )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroBinaryCodec[C[A]]] = { + )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroCodec[C[A]]] = { if (binding.isInstanceOf[Binding[?, ?]]) { val seqBinding = binding.asInstanceOf[Binding.Seq[Col, Elem]] D.instance(element.metadata).map { codec => - codec.valueType match { - case AvroBinaryCodec.booleanType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Boolean]]() { + typeTag(element) match { + case 5 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Boolean]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Boolean]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Boolean]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -277,9 +261,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -307,11 +291,11 @@ object AvroFormat encoder.writeInt(0) } } - case AvroBinaryCodec.byteType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Byte]]() { + case 6 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Byte]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Byte]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Byte]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -323,9 +307,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -353,11 +337,11 @@ object AvroFormat encoder.writeInt(0) } } - case AvroBinaryCodec.charType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Char]]() { + case 7 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Char]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Char]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Char]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -369,9 +353,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -399,11 +383,11 @@ object AvroFormat encoder.writeInt(0) } } - case AvroBinaryCodec.shortType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Short]]() { + case 8 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Short]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Short]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Short]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -415,9 +399,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -445,11 +429,11 @@ object AvroFormat encoder.writeInt(0) } } - case AvroBinaryCodec.floatType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Float]]() { + case 3 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Float]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Float]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Float]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -461,9 +445,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -491,11 +475,11 @@ object AvroFormat encoder.writeInt(0) } } - case AvroBinaryCodec.intType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Int]]() { + case 1 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Int]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Int]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Int]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -507,9 +491,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -537,11 +521,11 @@ object AvroFormat encoder.writeInt(0) } } - case AvroBinaryCodec.doubleType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Double]]() { + case 4 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Double]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Double]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Double]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -553,9 +537,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -583,11 +567,11 @@ object AvroFormat encoder.writeInt(0) } } - case AvroBinaryCodec.longType if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => - new AvroBinaryCodec[Col[Long]]() { + case 2 if seqBinding.deconstructor.isInstanceOf[SpecializedIndexed[Col]] => + new AvroCodec[Col[Long]]() { private[this] val deconstructor = seqBinding.deconstructor.asInstanceOf[SpecializedIndexed[Col]] private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Long]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Long]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -599,9 +583,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -630,10 +614,10 @@ object AvroFormat } } case _ => - new AvroBinaryCodec[Col[Elem]]() { + new AvroCodec[Col[Elem]]() { private[this] val deconstructor = seqBinding.deconstructor private[this] val constructor = seqBinding.constructor - private[this] val elementCodec = codec.asInstanceOf[AvroBinaryCodec[Elem]] + private[this] val elementCodec = codec.asInstanceOf[AvroCodec[Elem]] private[this] val elemClassTag = element.typeId.classTag.asInstanceOf[ClassTag[Elem]] val avroSchema: AvroSchema = AvroSchema.createArray(elementCodec.avroSchema) @@ -646,9 +630,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -679,7 +663,7 @@ object AvroFormat } } } else binding.asInstanceOf[BindingInstance[TC, ?, A]].instance - }.asInstanceOf[Lazy[AvroBinaryCodec[C[A]]]] + }.asInstanceOf[Lazy[AvroCodec[C[A]]]] override def deriveMap[F[_, _], M[_, _], K, V]( key: Reflect[F, K], @@ -690,15 +674,15 @@ object AvroFormat modifiers: Seq[Modifier.Reflect], defaultValue: Option[M[K, V]], examples: Seq[M[K, V]] - )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroBinaryCodec[M[K, V]]] = { + )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroCodec[M[K, V]]] = { if (binding.isInstanceOf[Binding[?, ?]]) { val mapBinding = binding.asInstanceOf[Binding.Map[Map, Key, Value]] D.instance(key.metadata).zip(D.instance(value.metadata)).map { case (codec1, codec2) => - new AvroBinaryCodec[Map[Key, Value]]() { + new AvroCodec[Map[Key, Value]]() { private[this] val deconstructor = mapBinding.deconstructor private[this] val constructor = mapBinding.constructor - private[this] val keyCodec = codec1.asInstanceOf[AvroBinaryCodec[Key]] - private[this] val valueCodec = codec2.asInstanceOf[AvroBinaryCodec[Value]] + private[this] val keyCodec = codec1.asInstanceOf[AvroCodec[Key]] + private[this] val valueCodec = codec2.asInstanceOf[AvroCodec[Value]] private[this] val keyReflect = key.asInstanceOf[Reflect.Bound[Key]] val avroSchema: AvroSchema = key.asPrimitive match { @@ -719,9 +703,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected map size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected map size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } while (size > 0) { @@ -762,7 +746,7 @@ object AvroFormat } } } else binding.asInstanceOf[BindingInstance[TC, ?, ?]].instance - }.asInstanceOf[Lazy[AvroBinaryCodec[M[K, V]]]] + }.asInstanceOf[Lazy[AvroCodec[M[K, V]]]] override def deriveDynamic[F[_, _]]( binding: Binding.Dynamic, @@ -770,10 +754,10 @@ object AvroFormat modifiers: Seq[Modifier.Reflect], defaultValue: Option[DynamicValue], examples: Seq[DynamicValue] - )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroBinaryCodec[DynamicValue]] = { + )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroCodec[DynamicValue]] = { if (binding.isInstanceOf[Binding[?, ?]]) Lazy(dynamicValueCodec) else binding.asInstanceOf[BindingInstance[TC, ?, ?]].instance - }.asInstanceOf[Lazy[AvroBinaryCodec[DynamicValue]]] + }.asInstanceOf[Lazy[AvroCodec[DynamicValue]]] def deriveWrapper[F[_, _], A, B]( wrapped: Reflect[F, B], @@ -783,25 +767,14 @@ object AvroFormat modifiers: Seq[Modifier.Reflect], defaultValue: Option[A], examples: Seq[A] - )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroBinaryCodec[A]] = { + )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[AvroCodec[A]] = { if (binding.isInstanceOf[Binding[?, ?]]) { val wrapperBinding = binding.asInstanceOf[Binding.Wrapper[A, Wrapped]] D.instance(wrapped.metadata).map { codec => - new AvroBinaryCodec[A](PrimitiveType.fromTypeId(typeId).fold(AvroBinaryCodec.objectType) { - case _: PrimitiveType.Boolean => AvroBinaryCodec.booleanType - case _: PrimitiveType.Byte => AvroBinaryCodec.byteType - case _: PrimitiveType.Char => AvroBinaryCodec.charType - case _: PrimitiveType.Short => AvroBinaryCodec.shortType - case _: PrimitiveType.Float => AvroBinaryCodec.floatType - case _: PrimitiveType.Int => AvroBinaryCodec.intType - case _: PrimitiveType.Double => AvroBinaryCodec.doubleType - case _: PrimitiveType.Long => AvroBinaryCodec.longType - case _: PrimitiveType.Unit.type => AvroBinaryCodec.unitType - case _ => AvroBinaryCodec.objectType - }) { + new AvroCodec[A] { private[this] val wrap = wrapperBinding.wrap private[this] val unwrap = wrapperBinding.unwrap - private[this] val wrappedCodec = codec.asInstanceOf[AvroBinaryCodec[Wrapped]] + private[this] val wrappedCodec = codec.asInstanceOf[AvroCodec[Wrapped]] val avroSchema: AvroSchema = wrappedCodec.avroSchema @@ -815,7 +788,7 @@ object AvroFormat } } } else binding.asInstanceOf[BindingInstance[TC, ?, A]].instance - }.asInstanceOf[Lazy[AvroBinaryCodec[A]]] + }.asInstanceOf[Lazy[AvroCodec[A]]] override def instanceOverrides: IndexedSeq[InstanceOverride] = { recursiveRecordCache.remove() @@ -832,8 +805,8 @@ object AvroFormat type TC[_] private[this] val recursiveRecordCache = - new ThreadLocal[java.util.HashMap[TypeId[?], (Array[AvroBinaryCodec[?]], AvroSchema)]] { - override def initialValue: java.util.HashMap[TypeId[?], (Array[AvroBinaryCodec[?]], AvroSchema)] = + new ThreadLocal[java.util.HashMap[TypeId[?], (Array[FieldInfo], AvroSchema)]] { + override def initialValue: java.util.HashMap[TypeId[?], (Array[FieldInfo], AvroSchema)] = new java.util.HashMap } private[this] val recordCounters = @@ -841,7 +814,7 @@ object AvroFormat override def initialValue: java.util.HashMap[(String, String), Int] = new java.util.HashMap } - private[this] val dynamicValueCodec = new AvroBinaryCodec[DynamicValue]() { + private[this] val dynamicValueCodec = new AvroCodec[DynamicValue]() { private[this] val spanPrimitive = new DynamicOptic.Node.Case("Primitive") private[this] val spanRecord = new DynamicOptic.Node.Case("Record") private[this] val spanVariant = new DynamicOptic.Node.Case("Variant") @@ -873,35 +846,35 @@ object AvroFormat "Unit", new java.util.ArrayList[AvroSchema.Field](0) ), - createPrimitiveValueAvroRecord("Boolean", AvroBinaryCodec.booleanCodec), - createPrimitiveValueAvroRecord("Byte", AvroBinaryCodec.byteCodec), - createPrimitiveValueAvroRecord("Short", AvroBinaryCodec.shortCodec), - createPrimitiveValueAvroRecord("Int", AvroBinaryCodec.intCodec), - createPrimitiveValueAvroRecord("Long", AvroBinaryCodec.longCodec), - createPrimitiveValueAvroRecord("Float", AvroBinaryCodec.floatCodec), - createPrimitiveValueAvroRecord("Double", AvroBinaryCodec.doubleCodec), - createPrimitiveValueAvroRecord("Char", AvroBinaryCodec.charCodec), - createPrimitiveValueAvroRecord("String", AvroBinaryCodec.stringCodec), - createPrimitiveValueAvroRecord("BigInt", AvroBinaryCodec.bigIntCodec), - createPrimitiveValueAvroRecord("BigDecimal", AvroBinaryCodec.bigDecimalCodec), - createPrimitiveValueAvroRecord("DayOfWeek", AvroBinaryCodec.dayOfWeekCodec), - createPrimitiveValueAvroRecord("Duration", AvroBinaryCodec.durationCodec), - createPrimitiveValueAvroRecord("Instant", AvroBinaryCodec.instantCodec), - createPrimitiveValueAvroRecord("LocalDate", AvroBinaryCodec.localDateCodec), - createPrimitiveValueAvroRecord("LocalDateTime", AvroBinaryCodec.localDateTimeCodec), - createPrimitiveValueAvroRecord("LocalTime", AvroBinaryCodec.localTimeCodec), - createPrimitiveValueAvroRecord("Month", AvroBinaryCodec.monthCodec), - createPrimitiveValueAvroRecord("MonthDay", AvroBinaryCodec.monthDayCodec), - createPrimitiveValueAvroRecord("OffsetDateTime", AvroBinaryCodec.offsetDateTimeCodec), - createPrimitiveValueAvroRecord("OffsetTime", AvroBinaryCodec.offsetTimeCodec), - createPrimitiveValueAvroRecord("Period", AvroBinaryCodec.periodCodec), - createPrimitiveValueAvroRecord("Year", AvroBinaryCodec.yearCodec), - createPrimitiveValueAvroRecord("YearMonth", AvroBinaryCodec.yearMonthCodec), - createPrimitiveValueAvroRecord("ZoneId", AvroBinaryCodec.zoneIdCodec), - createPrimitiveValueAvroRecord("ZoneOffset", AvroBinaryCodec.zoneOffsetCodec), - createPrimitiveValueAvroRecord("ZonedDateTime", AvroBinaryCodec.zonedDateTimeCodec), - createPrimitiveValueAvroRecord("Currency", AvroBinaryCodec.currencyCodec), - createPrimitiveValueAvroRecord("UUID", AvroBinaryCodec.uuidCodec) + createPrimitiveValueAvroRecord("Boolean", AvroCodec.booleanCodec), + createPrimitiveValueAvroRecord("Byte", AvroCodec.byteCodec), + createPrimitiveValueAvroRecord("Short", AvroCodec.shortCodec), + createPrimitiveValueAvroRecord("Int", AvroCodec.intCodec), + createPrimitiveValueAvroRecord("Long", AvroCodec.longCodec), + createPrimitiveValueAvroRecord("Float", AvroCodec.floatCodec), + createPrimitiveValueAvroRecord("Double", AvroCodec.doubleCodec), + createPrimitiveValueAvroRecord("Char", AvroCodec.charCodec), + createPrimitiveValueAvroRecord("String", AvroCodec.stringCodec), + createPrimitiveValueAvroRecord("BigInt", AvroCodec.bigIntCodec), + createPrimitiveValueAvroRecord("BigDecimal", AvroCodec.bigDecimalCodec), + createPrimitiveValueAvroRecord("DayOfWeek", AvroCodec.dayOfWeekCodec), + createPrimitiveValueAvroRecord("Duration", AvroCodec.durationCodec), + createPrimitiveValueAvroRecord("Instant", AvroCodec.instantCodec), + createPrimitiveValueAvroRecord("LocalDate", AvroCodec.localDateCodec), + createPrimitiveValueAvroRecord("LocalDateTime", AvroCodec.localDateTimeCodec), + createPrimitiveValueAvroRecord("LocalTime", AvroCodec.localTimeCodec), + createPrimitiveValueAvroRecord("Month", AvroCodec.monthCodec), + createPrimitiveValueAvroRecord("MonthDay", AvroCodec.monthDayCodec), + createPrimitiveValueAvroRecord("OffsetDateTime", AvroCodec.offsetDateTimeCodec), + createPrimitiveValueAvroRecord("OffsetTime", AvroCodec.offsetTimeCodec), + createPrimitiveValueAvroRecord("Period", AvroCodec.periodCodec), + createPrimitiveValueAvroRecord("Year", AvroCodec.yearCodec), + createPrimitiveValueAvroRecord("YearMonth", AvroCodec.yearMonthCodec), + createPrimitiveValueAvroRecord("ZoneId", AvroCodec.zoneIdCodec), + createPrimitiveValueAvroRecord("ZoneOffset", AvroCodec.zoneOffsetCodec), + createPrimitiveValueAvroRecord("ZonedDateTime", AvroCodec.zonedDateTimeCodec), + createPrimitiveValueAvroRecord("Currency", AvroCodec.currencyCodec), + createPrimitiveValueAvroRecord("UUID", AvroCodec.uuidCodec) ) ) ) @@ -913,7 +886,7 @@ object AvroFormat "fields", AvroSchema.createArray { val fieldFields = new java.util.ArrayList[AvroSchema.Field](2) - fieldFields.add(new AvroSchema.Field("name", AvroBinaryCodec.stringCodec.avroSchema)) + fieldFields.add(new AvroSchema.Field("name", AvroCodec.stringCodec.avroSchema)) fieldFields.add(new AvroSchema.Field("value", dynamicValue)) createAvroRecord("zio.blocks.schema.internal", "Field", fieldFields) } @@ -922,7 +895,7 @@ object AvroFormat createAvroRecord("zio.blocks.schema.DynamicValue", "Record", recordFields) }, { val variantFields = new java.util.ArrayList[AvroSchema.Field](2) - variantFields.add(new AvroSchema.Field("caseName", AvroBinaryCodec.stringCodec.avroSchema)) + variantFields.add(new AvroSchema.Field("caseName", AvroCodec.stringCodec.avroSchema)) variantFields.add(new AvroSchema.Field("value", dynamicValue)) createAvroRecord("zio.blocks.schema.DynamicValue", "Variant", variantFields) }, { @@ -964,38 +937,38 @@ object AvroFormat try { new DynamicValue.Primitive((idx: @scala.annotation.switch) match { case 0 => PrimitiveValue.Unit - case 1 => new PrimitiveValue.Boolean(AvroBinaryCodec.booleanCodec.decodeUnsafe(decoder)) - case 2 => new PrimitiveValue.Byte(AvroBinaryCodec.byteCodec.decodeUnsafe(decoder)) - case 3 => new PrimitiveValue.Short(AvroBinaryCodec.shortCodec.decodeUnsafe(decoder)) - case 4 => new PrimitiveValue.Int(AvroBinaryCodec.intCodec.decodeUnsafe(decoder)) - case 5 => new PrimitiveValue.Long(AvroBinaryCodec.longCodec.decodeUnsafe(decoder)) - case 6 => new PrimitiveValue.Float(AvroBinaryCodec.floatCodec.decodeUnsafe(decoder)) - case 7 => new PrimitiveValue.Double(AvroBinaryCodec.doubleCodec.decodeUnsafe(decoder)) - case 8 => new PrimitiveValue.Char(AvroBinaryCodec.charCodec.decodeUnsafe(decoder)) - case 9 => new PrimitiveValue.String(AvroBinaryCodec.stringCodec.decodeUnsafe(decoder)) - case 10 => new PrimitiveValue.BigInt(AvroBinaryCodec.bigIntCodec.decodeUnsafe(decoder)) - case 11 => new PrimitiveValue.BigDecimal(AvroBinaryCodec.bigDecimalCodec.decodeUnsafe(decoder)) - case 12 => new PrimitiveValue.DayOfWeek(AvroBinaryCodec.dayOfWeekCodec.decodeUnsafe(decoder)) - case 13 => new PrimitiveValue.Duration(AvroBinaryCodec.durationCodec.decodeUnsafe(decoder)) - case 14 => new PrimitiveValue.Instant(AvroBinaryCodec.instantCodec.decodeUnsafe(decoder)) - case 15 => new PrimitiveValue.LocalDate(AvroBinaryCodec.localDateCodec.decodeUnsafe(decoder)) + case 1 => new PrimitiveValue.Boolean(AvroCodec.booleanCodec.decodeUnsafe(decoder)) + case 2 => new PrimitiveValue.Byte(AvroCodec.byteCodec.decodeUnsafe(decoder)) + case 3 => new PrimitiveValue.Short(AvroCodec.shortCodec.decodeUnsafe(decoder)) + case 4 => new PrimitiveValue.Int(AvroCodec.intCodec.decodeUnsafe(decoder)) + case 5 => new PrimitiveValue.Long(AvroCodec.longCodec.decodeUnsafe(decoder)) + case 6 => new PrimitiveValue.Float(AvroCodec.floatCodec.decodeUnsafe(decoder)) + case 7 => new PrimitiveValue.Double(AvroCodec.doubleCodec.decodeUnsafe(decoder)) + case 8 => new PrimitiveValue.Char(AvroCodec.charCodec.decodeUnsafe(decoder)) + case 9 => new PrimitiveValue.String(AvroCodec.stringCodec.decodeUnsafe(decoder)) + case 10 => new PrimitiveValue.BigInt(AvroCodec.bigIntCodec.decodeUnsafe(decoder)) + case 11 => new PrimitiveValue.BigDecimal(AvroCodec.bigDecimalCodec.decodeUnsafe(decoder)) + case 12 => new PrimitiveValue.DayOfWeek(AvroCodec.dayOfWeekCodec.decodeUnsafe(decoder)) + case 13 => new PrimitiveValue.Duration(AvroCodec.durationCodec.decodeUnsafe(decoder)) + case 14 => new PrimitiveValue.Instant(AvroCodec.instantCodec.decodeUnsafe(decoder)) + case 15 => new PrimitiveValue.LocalDate(AvroCodec.localDateCodec.decodeUnsafe(decoder)) case 16 => - new PrimitiveValue.LocalDateTime(AvroBinaryCodec.localDateTimeCodec.decodeUnsafe(decoder)) - case 17 => new PrimitiveValue.LocalTime(AvroBinaryCodec.localTimeCodec.decodeUnsafe(decoder)) - case 18 => new PrimitiveValue.Month(AvroBinaryCodec.monthCodec.decodeUnsafe(decoder)) - case 19 => new PrimitiveValue.MonthDay(AvroBinaryCodec.monthDayCodec.decodeUnsafe(decoder)) + new PrimitiveValue.LocalDateTime(AvroCodec.localDateTimeCodec.decodeUnsafe(decoder)) + case 17 => new PrimitiveValue.LocalTime(AvroCodec.localTimeCodec.decodeUnsafe(decoder)) + case 18 => new PrimitiveValue.Month(AvroCodec.monthCodec.decodeUnsafe(decoder)) + case 19 => new PrimitiveValue.MonthDay(AvroCodec.monthDayCodec.decodeUnsafe(decoder)) case 20 => - new PrimitiveValue.OffsetDateTime(AvroBinaryCodec.offsetDateTimeCodec.decodeUnsafe(decoder)) - case 21 => new PrimitiveValue.OffsetTime(AvroBinaryCodec.offsetTimeCodec.decodeUnsafe(decoder)) - case 22 => new PrimitiveValue.Period(AvroBinaryCodec.periodCodec.decodeUnsafe(decoder)) - case 23 => new PrimitiveValue.Year(AvroBinaryCodec.yearCodec.decodeUnsafe(decoder)) - case 24 => new PrimitiveValue.YearMonth(AvroBinaryCodec.yearMonthCodec.decodeUnsafe(decoder)) - case 25 => new PrimitiveValue.ZoneId(AvroBinaryCodec.zoneIdCodec.decodeUnsafe(decoder)) - case 26 => new PrimitiveValue.ZoneOffset(AvroBinaryCodec.zoneOffsetCodec.decodeUnsafe(decoder)) + new PrimitiveValue.OffsetDateTime(AvroCodec.offsetDateTimeCodec.decodeUnsafe(decoder)) + case 21 => new PrimitiveValue.OffsetTime(AvroCodec.offsetTimeCodec.decodeUnsafe(decoder)) + case 22 => new PrimitiveValue.Period(AvroCodec.periodCodec.decodeUnsafe(decoder)) + case 23 => new PrimitiveValue.Year(AvroCodec.yearCodec.decodeUnsafe(decoder)) + case 24 => new PrimitiveValue.YearMonth(AvroCodec.yearMonthCodec.decodeUnsafe(decoder)) + case 25 => new PrimitiveValue.ZoneId(AvroCodec.zoneIdCodec.decodeUnsafe(decoder)) + case 26 => new PrimitiveValue.ZoneOffset(AvroCodec.zoneOffsetCodec.decodeUnsafe(decoder)) case 27 => - new PrimitiveValue.ZonedDateTime(AvroBinaryCodec.zonedDateTimeCodec.decodeUnsafe(decoder)) - case 28 => new PrimitiveValue.Currency(AvroBinaryCodec.currencyCodec.decodeUnsafe(decoder)) - case _ => new PrimitiveValue.UUID(AvroBinaryCodec.uuidCodec.decodeUnsafe(decoder)) + new PrimitiveValue.ZonedDateTime(AvroCodec.zonedDateTimeCodec.decodeUnsafe(decoder)) + case 28 => new PrimitiveValue.Currency(AvroCodec.currencyCodec.decodeUnsafe(decoder)) + case _ => new PrimitiveValue.UUID(AvroCodec.uuidCodec.decodeUnsafe(decoder)) }) } catch { case error if NonFatal(error) => decodeError(spanValue, error) @@ -1012,9 +985,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } while (size > 0) { @@ -1061,9 +1034,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } try { @@ -1090,9 +1063,9 @@ object AvroFormat size = decoder.readInt() size > 0 }) { - if (count + size > AvroBinaryCodec.maxCollectionSize) { + if (count + size > AvroCodec.maxCollectionSize) { decodeError( - s"Expected collection size not greater than ${AvroBinaryCodec.maxCollectionSize}, got ${count + size}" + s"Expected collection size not greater than ${AvroCodec.maxCollectionSize}, got ${count + size}" ) } while (size > 0) { @@ -1131,91 +1104,91 @@ object AvroFormat encoder.writeInt(0) case v: PrimitiveValue.Boolean => encoder.writeInt(1) - AvroBinaryCodec.booleanCodec.encode(v.value, encoder) + AvroCodec.booleanCodec.encode(v.value, encoder) case v: PrimitiveValue.Byte => encoder.writeInt(2) - AvroBinaryCodec.byteCodec.encode(v.value, encoder) + AvroCodec.byteCodec.encode(v.value, encoder) case v: PrimitiveValue.Short => encoder.writeInt(3) - AvroBinaryCodec.shortCodec.encode(v.value, encoder) + AvroCodec.shortCodec.encode(v.value, encoder) case v: PrimitiveValue.Int => encoder.writeInt(4) - AvroBinaryCodec.intCodec.encode(v.value, encoder) + AvroCodec.intCodec.encode(v.value, encoder) case v: PrimitiveValue.Long => encoder.writeInt(5) - AvroBinaryCodec.longCodec.encode(v.value, encoder) + AvroCodec.longCodec.encode(v.value, encoder) case v: PrimitiveValue.Float => encoder.writeInt(6) - AvroBinaryCodec.floatCodec.encode(v.value, encoder) + AvroCodec.floatCodec.encode(v.value, encoder) case v: PrimitiveValue.Double => encoder.writeInt(7) - AvroBinaryCodec.doubleCodec.encode(v.value, encoder) + AvroCodec.doubleCodec.encode(v.value, encoder) case v: PrimitiveValue.Char => encoder.writeInt(8) - AvroBinaryCodec.charCodec.encode(v.value, encoder) + AvroCodec.charCodec.encode(v.value, encoder) case v: PrimitiveValue.String => encoder.writeInt(9) - AvroBinaryCodec.stringCodec.encode(v.value, encoder) + AvroCodec.stringCodec.encode(v.value, encoder) case v: PrimitiveValue.BigInt => encoder.writeInt(10) - AvroBinaryCodec.bigIntCodec.encode(v.value, encoder) + AvroCodec.bigIntCodec.encode(v.value, encoder) case v: PrimitiveValue.BigDecimal => encoder.writeInt(11) - AvroBinaryCodec.bigDecimalCodec.encode(v.value, encoder) + AvroCodec.bigDecimalCodec.encode(v.value, encoder) case v: PrimitiveValue.DayOfWeek => encoder.writeInt(12) - AvroBinaryCodec.dayOfWeekCodec.encode(v.value, encoder) + AvroCodec.dayOfWeekCodec.encode(v.value, encoder) case v: PrimitiveValue.Duration => encoder.writeInt(13) - AvroBinaryCodec.durationCodec.encode(v.value, encoder) + AvroCodec.durationCodec.encode(v.value, encoder) case v: PrimitiveValue.Instant => encoder.writeInt(14) - AvroBinaryCodec.instantCodec.encode(v.value, encoder) + AvroCodec.instantCodec.encode(v.value, encoder) case v: PrimitiveValue.LocalDate => encoder.writeInt(15) - AvroBinaryCodec.localDateCodec.encode(v.value, encoder) + AvroCodec.localDateCodec.encode(v.value, encoder) case v: PrimitiveValue.LocalDateTime => encoder.writeInt(16) - AvroBinaryCodec.localDateTimeCodec.encode(v.value, encoder) + AvroCodec.localDateTimeCodec.encode(v.value, encoder) case v: PrimitiveValue.LocalTime => encoder.writeInt(17) - AvroBinaryCodec.localTimeCodec.encode(v.value, encoder) + AvroCodec.localTimeCodec.encode(v.value, encoder) case v: PrimitiveValue.Month => encoder.writeInt(18) - AvroBinaryCodec.monthCodec.encode(v.value, encoder) + AvroCodec.monthCodec.encode(v.value, encoder) case v: PrimitiveValue.MonthDay => encoder.writeInt(19) - AvroBinaryCodec.monthDayCodec.encode(v.value, encoder) + AvroCodec.monthDayCodec.encode(v.value, encoder) case v: PrimitiveValue.OffsetDateTime => encoder.writeInt(20) - AvroBinaryCodec.offsetDateTimeCodec.encode(v.value, encoder) + AvroCodec.offsetDateTimeCodec.encode(v.value, encoder) case v: PrimitiveValue.OffsetTime => encoder.writeInt(21) - AvroBinaryCodec.offsetTimeCodec.encode(v.value, encoder) + AvroCodec.offsetTimeCodec.encode(v.value, encoder) case v: PrimitiveValue.Period => encoder.writeInt(22) - AvroBinaryCodec.periodCodec.encode(v.value, encoder) + AvroCodec.periodCodec.encode(v.value, encoder) case v: PrimitiveValue.Year => encoder.writeInt(23) - AvroBinaryCodec.yearCodec.encode(v.value, encoder) + AvroCodec.yearCodec.encode(v.value, encoder) case v: PrimitiveValue.YearMonth => encoder.writeInt(24) - AvroBinaryCodec.yearMonthCodec.encode(v.value, encoder) + AvroCodec.yearMonthCodec.encode(v.value, encoder) case v: PrimitiveValue.ZoneId => encoder.writeInt(25) - AvroBinaryCodec.zoneIdCodec.encode(v.value, encoder) + AvroCodec.zoneIdCodec.encode(v.value, encoder) case v: PrimitiveValue.ZoneOffset => encoder.writeInt(26) - AvroBinaryCodec.zoneOffsetCodec.encode(v.value, encoder) + AvroCodec.zoneOffsetCodec.encode(v.value, encoder) case v: PrimitiveValue.ZonedDateTime => encoder.writeInt(27) - AvroBinaryCodec.zonedDateTimeCodec.encode(v.value, encoder) + AvroCodec.zonedDateTimeCodec.encode(v.value, encoder) case v: PrimitiveValue.Currency => encoder.writeInt(28) - AvroBinaryCodec.currencyCodec.encode(v.value, encoder) + AvroCodec.currencyCodec.encode(v.value, encoder) case v: PrimitiveValue.UUID => encoder.writeInt(29) - AvroBinaryCodec.uuidCodec.encode(v.value, encoder) + AvroCodec.uuidCodec.encode(v.value, encoder) } case record: DynamicValue.Record => encoder.writeInt(1) @@ -1265,7 +1238,7 @@ object AvroFormat encoder.writeInt(5) } - private[this] def createPrimitiveValueAvroRecord(name: String, codec: AvroBinaryCodec[?]): AvroSchema = { + private[this] def createPrimitiveValueAvroRecord(name: String, codec: AvroCodec[?]): AvroSchema = { val avroSchema = codec.avroSchema val fields = new java.util.ArrayList[AvroSchema.Field](1) fields.add(new AvroSchema.Field("value", avroSchema)) @@ -1285,5 +1258,47 @@ object AvroFormat if (fields eq null) AvroSchema.createRecord(recordName, null, namespace, false) else AvroSchema.createRecord(recordName, null, namespace, false, fields) } + + private def registerOffset[F[_, _], A](reflect: Reflect[F, A]): RegisterOffset.RegisterOffset = + Reflect.unwrapToPrimitiveTypeOption(reflect) match { + case Some(primitiveType) => + primitiveType match { + case _: PrimitiveType.Unit.type => 0L + case _: PrimitiveType.Boolean => RegisterOffset.incrementBooleansAndBytes(0L) + case _: PrimitiveType.Byte => RegisterOffset.incrementBooleansAndBytes(0L) + case _: PrimitiveType.Char => RegisterOffset.incrementCharsAndShorts(0L) + case _: PrimitiveType.Short => RegisterOffset.incrementCharsAndShorts(0L) + case _: PrimitiveType.Float => RegisterOffset.incrementFloatsAndInts(0L) + case _: PrimitiveType.Int => RegisterOffset.incrementFloatsAndInts(0L) + case _: PrimitiveType.Double => RegisterOffset.incrementDoublesAndLongs(0L) + case _: PrimitiveType.Long => RegisterOffset.incrementDoublesAndLongs(0L) + case _ => RegisterOffset.incrementObjects(0L) + } + case _ => RegisterOffset.incrementObjects(0L) + } + + private def typeTag[F[_, _], A](reflect: Reflect[F, A]): Int = + Reflect.unwrapToPrimitiveTypeOption(reflect) match { + case Some(primitiveType) => + primitiveType match { + case _: PrimitiveType.Unit.type => 9 + case _: PrimitiveType.Boolean => 5 + case _: PrimitiveType.Byte => 6 + case _: PrimitiveType.Char => 7 + case _: PrimitiveType.Short => 8 + case _: PrimitiveType.Float => 3 + case _: PrimitiveType.Int => 1 + case _: PrimitiveType.Double => 4 + case _: PrimitiveType.Long => 2 + case _ => 0 + } + case _ => 0 + } } ) + +private[avro] case class FieldInfo( + codec: AvroCodec[?], + typeTag: Int, + offset: RegisterOffset.RegisterOffset = 0L +) diff --git a/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroFormatSpec.scala b/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroFormatSpec.scala index e62a70c12b..d30262d09a 100644 --- a/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroFormatSpec.scala +++ b/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroFormatSpec.scala @@ -262,7 +262,7 @@ object AvroFormatSpec extends SchemaBaseSpec { .deriving(AvroFormat.deriver) .instance( Record1.i, - new AvroBinaryCodec[Int](AvroBinaryCodec.intType) { + new AvroCodec[Int] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.STRING) def decodeUnsafe(decoder: BinaryDecoder): Int = java.lang.Integer.valueOf(decoder.readString()) @@ -282,7 +282,7 @@ object AvroFormatSpec extends SchemaBaseSpec { .deriving(AvroFormat.deriver) .instance( TypeId.int, - new AvroBinaryCodec[Int](AvroBinaryCodec.intType) { + new AvroCodec[Int] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.STRING) def decodeUnsafe(decoder: BinaryDecoder): Int = java.lang.Integer.valueOf(decoder.readString()) @@ -302,7 +302,7 @@ object AvroFormatSpec extends SchemaBaseSpec { .deriving(AvroFormat.deriver) .instance( Record4.hidden, - new AvroBinaryCodec[Unit](AvroBinaryCodec.unitType) { + new AvroCodec[Unit] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.STRING) def decodeUnsafe(decoder: BinaryDecoder): Unit = decoder.readString() @@ -322,7 +322,7 @@ object AvroFormatSpec extends SchemaBaseSpec { .deriving(AvroFormat.deriver) .instance( Record4.optKey_None, - new AvroBinaryCodec[None.type](AvroBinaryCodec.unitType) { + new AvroCodec[None.type] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.STRING) def decodeUnsafe(decoder: BinaryDecoder): None.type = { @@ -342,7 +342,7 @@ object AvroFormatSpec extends SchemaBaseSpec { roundTrip(Record4((), None), 5, codec) }, test("record with a custom codec for nested record injected by optic") { - val codec1 = new AvroBinaryCodec[Record1]() { + val codec1 = new AvroCodec[Record1]() { private val codec = Record1.schema.derive(AvroFormat) val avroSchema: AvroSchema = @@ -385,7 +385,7 @@ object AvroFormatSpec extends SchemaBaseSpec { .deriving(AvroFormat.deriver) .instance( TypeId.int, - new AvroBinaryCodec[Int](AvroBinaryCodec.intType) { + new AvroCodec[Int] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.STRING) def decodeUnsafe(decoder: BinaryDecoder): Int = java.lang.Integer.valueOf(decoder.readString()) @@ -395,7 +395,7 @@ object AvroFormatSpec extends SchemaBaseSpec { ) .instance( Record2.r1_2_i, - new AvroBinaryCodec[Int](AvroBinaryCodec.intType) { + new AvroCodec[Int] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.DOUBLE) def decodeUnsafe(decoder: BinaryDecoder): Int = decoder.readDouble().toInt @@ -422,7 +422,7 @@ object AvroFormatSpec extends SchemaBaseSpec { .deriving(AvroFormat.deriver) .instance( Record1.schema.reflect.typeId, - new AvroBinaryCodec[Record1]() { + new AvroCodec[Record1]() { private val codec = Record1.schema.derive(AvroFormat) val avroSchema: AvroSchema = @@ -462,7 +462,7 @@ object AvroFormatSpec extends SchemaBaseSpec { .deriving(AvroFormat.deriver) .instance( Recursive.i, - new AvroBinaryCodec[Int](AvroBinaryCodec.intType) { + new AvroCodec[Int] { val avroSchema: AvroSchema = AvroSchema.create(AvroSchema.Type.STRING) def decodeUnsafe(decoder: BinaryDecoder): Int = java.lang.Integer.valueOf(decoder.readString()) @@ -932,7 +932,7 @@ object AvroFormatSpec extends SchemaBaseSpec { ) ) ) - val codec1 = new AvroBinaryCodec[DynamicValue]() { + val codec1 = new AvroCodec[DynamicValue]() { private val codec = Schema[DynamicValue].derive(AvroFormat) val avroSchema: AvroSchema = diff --git a/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroTestUtils.scala b/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroTestUtils.scala index 341cd13e80..50b059160e 100644 --- a/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroTestUtils.scala +++ b/schema-avro/src/test/scala/zio/blocks/schema/avro/AvroTestUtils.scala @@ -29,23 +29,23 @@ import java.util.concurrent.ConcurrentHashMap import scala.collection.immutable.ArraySeq object AvroTestUtils { - private[this] val codecs = new ConcurrentHashMap[Schema[?], AvroBinaryCodec[?]]() + private[this] val codecs = new ConcurrentHashMap[Schema[?], AvroCodec[?]]() - private[this] def codec[A](schema: Schema[A]): AvroBinaryCodec[A] = + private[this] def codec[A](schema: Schema[A]): AvroCodec[A] = codecs .computeIfAbsent(schema, (s: Schema[?]) => s.deriving(AvroFormat.deriver).derive) - .asInstanceOf[AvroBinaryCodec[A]] + .asInstanceOf[AvroCodec[A]] def avroSchema[A](expectedAvroSchemaJson: String)(implicit schema: Schema[A]): TestResult = avroSchema(expectedAvroSchemaJson, codec(schema)) - def avroSchema[A](expectedAvroSchemaJson: String, codec: AvroBinaryCodec[A]): TestResult = + def avroSchema[A](expectedAvroSchemaJson: String, codec: AvroCodec[A]): TestResult = assert(codec.avroSchema.toString)(equalTo(expectedAvroSchemaJson)) def roundTrip[A](value: A, expectedLength: Int)(implicit schema: Schema[A]): TestResult = roundTrip(value, expectedLength, codec(schema)) - def roundTrip[A](value: A, expectedLength: Int, codec: AvroBinaryCodec[A]): TestResult = { + def roundTrip[A](value: A, expectedLength: Int, codec: AvroCodec[A]): TestResult = { val heapByteBuffer = ByteBuffer.allocate(maxBufSize) codec.encode(value, heapByteBuffer) val encodedBySchema1 = util.Arrays.copyOf(heapByteBuffer.array, heapByteBuffer.position) @@ -87,7 +87,7 @@ object AvroTestUtils { def decodeError[A](bytes: Array[Byte], error: String)(implicit schema: Schema[A]): TestResult = decodeError(bytes, codec(schema), error) - def decodeError[A](bytes: Array[Byte], codec: AvroBinaryCodec[A], error: String): TestResult = + def decodeError[A](bytes: Array[Byte], codec: AvroCodec[A], error: String): TestResult = assert(codec.decode(bytes))(isLeft(hasError(error))) && assert(codec.decode(toInputStream(bytes)))(isLeft(hasError(error))) && assert(codec.decode(toHeapByteBuffer(bytes)))(isLeft(hasError(error))) &&