I'd like to encode Array[Byte]
fields of my case classes as Base64 strings. For some reason Circe doesn't pick up my codec using default one instead that converts byte array into json array of ints.
What should I do to fix it ? Here is my minimized code
import io.circe.generic.JsonCodec
sealed trait DocumentAttribute
@JsonCodec
sealed case class DAAudio(title: Option[String], performer: Option[String], waveform: Option[Array[Byte]], duration: Int) extends DocumentAttribute
@JsonCodec
sealed case class DAFilename(fileName: String) extends DocumentAttribute
object CirceEncodersDecoders {
import io.circe._
import io.circe.generic.extras._
import io.circe.generic.extras.semiauto._
implicit val arrayByteEncoder: Encoder[Array[Byte]] = Encoder.encodeString.contramap[Array[Byte]] { bytes ⇒
Base64.getEncoder.encodeToString(bytes)
}
val printer: Printer = Printer.noSpaces.copy(dropNullValues = true, reuseWriters = true)
implicit val config: Configuration = Configuration.default.withDiscriminator("kind").withSnakeCaseConstructorNames.withSnakeCaseMemberNames
implicit val DocumentAttributeEncoder: Encoder[DocumentAttribute] = deriveEncoder
implicit val DocumentAttributeDecoder: Decoder[DocumentAttribute] = deriveDecoder
}
object main {
def main(args: Array[String]): Unit = {
import CirceEncodersDecoders._
import io.circe.parser._
import io.circe.syntax._
val attributes: List[DocumentAttribute] = List(
DAAudio(Some("title"), Some("perform"), Some(List(1, 2, 3, 4, 5).map(_.toByte).toArray), 15),
DAFilename("filename")
)
val j2 = attributes.asJson
val decoded2 = decode[List[DocumentAttribute]](j2.noSpaces)
println(decoded2)
}
}