sksamuel / avro4s

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

DataFormat does not use Custom string Encoder #801

Open linkleonard opened 9 months ago

linkleonard commented 9 months ago

Hello,

I'm defining a encoding for java.util.Currency where the underlying format is just a string. However, when I attempt to use it with the DataFormat, it blows up with a failed cast operation. I've traced it down to this line here. Wondering if there are any issues changing this to call the encoder, for derived types like this?

// codec
implicit object CurrencyCodec extends Codec[Currency] {
  override def schemaFor: SchemaFor[Currency] = 
    SchemaFor[Currency](SchemaBuilder.builder.stringType())

  def encode(value: Currency): AnyRef =
    Encoder.StringEncoder.encode(value.getCurrencyCode)

  override def decode(value: Any): Currency =
    Currency.getInstance(Decoder.StringDecoder.decode(value))
}
// spec
val currency = Currency.getInstance("USD")
val byteStream = new ByteArrayOutputStream
val outputStream = AvroOutputStream.data(CurrencyCodec).to(byteStream).build()
try {
  outputStream.write(currency)
  outputStream.flush()
} finally {
  outputStream.close()
}

byteStream.toByteArray
org.apache.avro.file.DataFileWriter$AppendWriteException: java.lang.ClassCastException: class java.util.Currency cannot be cast to class java.lang.CharSequence (java.util.Currency and java.lang.CharSequence are in module java.base of loader 'bootstrap')
org.apache.avro.file.DataFileWriter$AppendWriteException: java.lang.ClassCastException: class java.util.Currency cannot be cast to class java.lang.CharSequence (java.util.Currency and java.lang.CharSequence are in module java.base of loader 'bootstrap')
    at org.apache.avro.file.DataFileWriter.append(DataFileWriter.java:317)
    at com.sksamuel.avro4s.AvroDataOutputStream.$anonfun$x$1$1(AvroDataOutputStream.scala:30)
    at com.sksamuel.avro4s.AvroDataOutputStream.$anonfun$x$1$1$adapted(AvroDataOutputStream.scala:30)
    at com.sksamuel.avro4s.AvroDataOutputStream.write(AvroDataOutputStream.scala:48)
    at CurrencyCodecSpec.$anonfun$new$2(CurrencyCodecSpec.scala:19)