sksamuel / avro4s

Avro schema generation and serialization / deserialization for Scala
Apache License 2.0
714 stars 236 forks source link

Decoder not implicitly available for value classes in Scala 3 #812

Open dvgica opened 7 months ago

dvgica commented 7 months ago

I'm upgrading some 2.13 code to 3.3.1. It makes use of value classes which Avro4s was previously able to derive a Decoder for, but in Scala 3 cannot.

In short, I think this should work with Avro4s 5.0.8, but does not (Scastie):

case class Thing(value: String) extends AnyVal

import com.sksamuel.avro4s.Decoder

println(implicitly[Decoder[Thing]])

gives

No given instance of type com.sksamuel.avro4s.Decoder[Playground.Thing] was found for parameter e of method implicitly in object Predef.
I found:

    com.sksamuel.avro4s.Decoder.autoDerived[Playground.Thing](
      /* missing */summon[deriving.Mirror.Of[Playground.Thing]])

But Failed to synthesize an instance of type deriving.Mirror.Of[Playground.Thing]:
    * class Thing is not a generic product because it is a value class
    * class Thing is not a generic sum because it is not a sealed class.

In Avro4s 4.1.1 it works fine.

Am I missing something here?

dvgica commented 7 months ago

It appears that this issue also applies to Encoder and SchemaFor.

I have worked around it for now by defining my own implicits:

import com.sksamuel.avro4s.Decoder
import com.sksamuel.avro4s.Encoder
import com.sksamuel.avro4s.SchemaFor
import com.sksamuel.avro4s.decoders.StringDecoder
import com.sksamuel.avro4s.encoders.StringEncoder
import com.sksamuel.avro4s.schemas.JavaStringSchemaFor

implicit val thingDecoder: Decoder[Thing] = StringDecoder.map(Thing(_))
implicit val thingEncoder: Encoder[Thing] = StringEncoder.contramap(_.value)
implicit val thingSchemaFor: SchemaFor[Thing] = JavaStringSchemaFor.forType[Thing]