All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sksamuel.avro4s.decoders.options.scala Maven / Gradle / Ivy

package com.sksamuel.avro4s.decoders

import com.sksamuel.avro4s.Decoder
import com.sksamuel.avro4s.Encoder
import org.apache.avro.Schema

import scala.jdk.CollectionConverters.*

class OptionDecoder[T](decoder: Decoder[T]) extends Decoder[Option[T]] {

  override def decode(schema: Schema): Any => Option[T] = {
    // nullables must be encoded with a union of 2 elements, one of which is null
    require(schema.getType == Schema.Type.UNION, {
      "Options can only be encoded with a UNION schema"
    })
    require(schema.getTypes.size() >= 2, {
      "An option should be encoded with a UNION schema with at least 2 element types"
    })
    val (isNull, isNotNull) = schema.getTypes().asScala.toList.partition(_.getType() == Schema.Type.NULL)
    require(isNull.size == 1, s"exactly one of the schemas must be null (found ${isNull.size})")
    val elementSchema = isNotNull match {
      case List(single) => single
      case more => Schema.createUnion(more.asJava)
    }

    val decode = decoder.decode(elementSchema)
    { value => if (value == null) None else Some(decode(value)) }
  }
}

trait OptionDecoders:
  given[T](using decoder: Decoder[T]): Decoder[Option[T]] = new OptionDecoder[T](decoder)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy