Example that fails (using Fruit sealed trait from SealedTraitDecoderTest):
test("support round-trip for sealed traits of case classes") {
@AvroNamespace("market")
case class Garden(fruit1: Fruit, fruit2: Fruit)
val schema = AvroSchema[Garden]
val garden = Garden(Apple(2.45), Orange("blue"))
val record = Encoder[Garden].encode(schema)(garden)
val gardenAgain = Decoder[Garden].decode(schema)(record)
gardenAgain shouldBe garden
}
Error is
com.sksamuel.avro4s.Avro4sConfigurationException: Cannot find subschema for type [com.sksamuel.avro4s.record.decoder.Apple] in [{"type":"record","name":"Apple","namespace":"market","fields":[{"name":"weight","type":"double"}]}, {"type":"record","name":"Orange","namespace":"market","fields":[{"name":"color","type":"string"}]}]
Digging a bit deeper into the encoder/decoder machinery, I found out that typeutils.Names are created differently for TypeUnions.encoder and TypeUnions.decoder. Former does utilize proper namespace (from Annotations), latter - does not.
What I have done is basically passed Annotations to decoder via main constructor, the same as it is done for encoder. And it solved the issue.
// avro4s-core/src/main/scala/com/sksamuel/avro4s/decoders/unions.scala
val decodersByName = ctx.subtypes.map { st =>
val annos: Annotations = Annotations(st.annotations) // <-- this was added
val names = Names(st.typeInfo, annos) // <-- and passed here
val subschema = SchemaHelper.extractTraitSubschema(names.fullName, schema)
names.fullName -> st.typeclass.decode(subschema)
}...
And now the question: is it a bug or is it me who cannot use library properly? I am very novice in avro4s, so I could be wrong in my discoveries ;)
Oh, and it is the latest version: 5.0.7 (i.e. for Scala 3)
Example that fails (using
Fruit
sealed trait fromSealedTraitDecoderTest
):Error is
Digging a bit deeper into the encoder/decoder machinery, I found out that
typeutils.Names
are created differently forTypeUnions.encoder
andTypeUnions.decoder
. Former does utilize proper namespace (from Annotations), latter - does not.What I have done is basically passed Annotations to decoder via main constructor, the same as it is done for encoder. And it solved the issue.
And now the question: is it a bug or is it me who cannot use library properly? I am very novice in avro4s, so I could be wrong in my discoveries ;) Oh, and it is the latest version: 5.0.7 (i.e. for Scala 3)