implicit def ptIterable[T, C[T]]()

in parquet/src/main/scala/magnolify/parquet/ParquetField.scala [305:369]


  implicit def ptIterable[T, C[T]](implicit
    t: ParquetField[T],
    ti: C[T] => Iterable[T],
    fc: FactoryCompat[T, C[T]],
    pa: ParquetArray
  ): ParquetField[C[T]] = {
    new ParquetField[C[T]] {
      override val hasAvroArray: Boolean = pa match {
        case ParquetArray.default               => false
        case ParquetArray.AvroCompat.avroCompat => true
      }

      override def buildSchema(cm: CaseMapper): Type = {
        val repeatedSchema = Schema.setRepetition(t.schema(cm), Repetition.REPEATED)
        if (hasAvroArray) {
          Types
            .requiredGroup()
            .addField(Schema.rename(repeatedSchema, AvroArrayField))
            .as(LogicalTypeAnnotation.listType())
            .named("iterable")
        } else {
          repeatedSchema
        }
      }

      override protected val isGroup: Boolean = hasAvroArray
      override protected def isEmpty(v: C[T]): Boolean = v.forall(t.isEmpty)

      override def write(c: RecordConsumer, v: C[T])(cm: CaseMapper): Unit =
        if (hasAvroArray) {
          c.startField(AvroArrayField, 0)
          v.foreach(t.writeGroup(c, _)(cm))
          c.endField(AvroArrayField, 0)
        } else {
          v.foreach(t.writeGroup(c, _)(cm))
        }

      override def newConverter: TypeConverter[C[T]] = {
        val buffered = t.newConverter
          .asInstanceOf[TypeConverter.Buffered[T]]
          .withRepetition(Repetition.REPEATED)
        val arrayConverter = new TypeConverter.Delegate[T, C[T]](buffered) {
          override def get: C[T] = inner.get(fc.fromSpecific)
        }

        if (hasAvroArray) {
          new GroupConverter with TypeConverter.Buffered[C[T]] {
            override def getConverter(fieldIndex: Int): Converter = {
              require(fieldIndex == 0, "Avro array field index != 0")
              arrayConverter
            }
            override def start(): Unit = ()
            override def end(): Unit = addValue(arrayConverter.get)
            override def get: C[T] = get(_.headOption.getOrElse(fc.newBuilder.result()))
          }
        } else {
          arrayConverter
        }
      }

      override def fieldDocs(cm: CaseMapper): Map[String, String] = t.fieldDocs(cm)

      override val typeDoc: Option[String] = None
    }
  }