zio-schema icon indicating copy to clipboard operation
zio-schema copied to clipboard

Avro schema for Option[Enum] failing to decode

Open mattdavpir opened this issue 1 year ago • 4 comments

Hey,

We've tried making a field that was an enum into an Option (i.e. rather than myFIeld: MyEnum it's now myField: Option[MyEnum]) and it seems that when decoding the bytes we enter decodeGenericEnum with an enumCaseName of zio.schema.codec.avro.wrapper_hashed_n1189833338rather than the proper enum name.

Simple example:

object AvroSerde:
  def create[A: Schema]: Serde[Any, A] =
    given BinaryCodec[A] = AvroCodec.schemaBasedBinaryCodec
    Serde.byteArray.inmapM(decodeBytes[A])(encodeA[A])

  private def decodeBytes[A](using codec: BinaryCodec[A]) =
    (bytes: Array[Byte]) => ZIO.fromEither[Throwable, A](codec.decode(Chunk.fromArray(bytes)))

  private def encodeA[A](using codec: BinaryCodec[A]) =
    (a: A) => ZIO.succeed(codec.encode(a).toArray)

object Test extends ZIOAppDefault:
  enum MyEnum:
    case A, B, C

  final case class MyType(id: Long, myEnum: MyEnum)

  final case class MyTypeWithOption(id: Long, myEnum: Option[MyEnum])

  given Schema[MyType] = DeriveSchema.gen[MyType]

  given Schema[MyTypeWithOption] = DeriveSchema.gen[MyTypeWithOption]

  val myTypeSerde = AvroSerde.create[MyType]
  val myTypeWithOptionSerde = AvroSerde.create[MyTypeWithOption]

  val topic = "blah"

  override def run: ZIO[Any with ZIOAppArgs with Scope, Any, Any] =
    for
      bytes  <- myTypeSerde.serialize(topic, new RecordHeaders(), MyType(123L, MyEnum.B))
      myType <- myTypeSerde.deserialize(topic, new RecordHeaders(), bytes)
      _      <- ZIO.logInfo(myType.toString) // Prints "MyType(123,B)"

      // This serialize throws an exception for me, which is not the error that I'm seeing in my real project beause we 
      // aren't the ones serializing the data, but it looks related
      bytesOption  <- myTypeWithOptionSerde.serialize(topic, new RecordHeaders(), MyTypeWithOption(123L, Some(MyEnum.B)))
      myTypeOption <- myTypeWithOptionSerde.deserialize(topic, new RecordHeaders(), bytesOption)
      _            <- ZIO.logInfo(myType.toString)
    yield ()

mattdavpir avatar Sep 19 '23 16:09 mattdavpir

/bounty $100

jdegoes avatar Jan 08 '24 10:01 jdegoes

~~## 💎 $100 bounty • ZIO~~

~~### Steps to solve:~~ ~~1. Start working: Comment /attempt #608 with your implementation plan~~ ~~2. Submit work: Create a pull request including /claim #608 in the PR body to claim the bounty~~ ~~3. Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts~~

~~Thank you for contributing to zio/zio-schema!~~

~~Add a bountyShare on socials~~

Attempt Started (GMT+0) Solution
🟢 @pablf #659

algora-pbc[bot] avatar Jan 08 '24 10:01 algora-pbc[bot]

💡 @pablf submitted a pull request that claims the bounty. You can visit your bounty board to reward.

algora-pbc[bot] avatar Feb 01 '24 22:02 algora-pbc[bot]

🎉🎈 @pablf has been awarded $100! 🎈🎊

algora-pbc[bot] avatar Feb 02 '24 13:02 algora-pbc[bot]