in avro/src/main/scala/magnolify/avro/AvroType.scala [95:150]
def join[T](caseClass: CaseClass[Typeclass, T]): AvroField[T] = {
if (caseClass.isValueClass) {
val p = caseClass.parameters.head
val tc = p.typeclass
new AvroField[T] {
override type FromT = tc.FromT
override type ToT = tc.ToT
override protected def buildSchema(cm: CaseMapper): Schema = tc.buildSchema(cm)
override def from(v: FromT)(cm: CaseMapper): T = caseClass.construct(_ => tc.fromAny(v)(cm))
override def to(v: T)(cm: CaseMapper): ToT = tc.to(p.dereference(v))(cm)
}
} else {
new Record[T] {
override protected def buildSchema(cm: CaseMapper): Schema = Schema
.createRecord(
caseClass.typeName.short,
getDoc(caseClass.annotations, caseClass.typeName.full),
caseClass.typeName.owner,
false,
caseClass.parameters.map { p =>
new Schema.Field(
cm.map(p.label),
p.typeclass.schema(cm),
getDoc(p.annotations, s"${caseClass.typeName.full}#${p.label}"),
p.default
.map(d => p.typeclass.makeDefault(d)(cm))
.getOrElse(p.typeclass.fallbackDefault)
)
}.asJava
)
// `JacksonUtils.toJson` expects `Map[String, Any]` for `RECORD` defaults
override def makeDefault(d: T)(cm: CaseMapper): ju.Map[String, Any] = {
caseClass.parameters
.map { p =>
val name = cm.map(p.label)
val value = p.typeclass.makeDefault(p.dereference(d))(cm)
name -> value
}
.toMap
.asJava
}
override def from(v: GenericRecord)(cm: CaseMapper): T =
caseClass.construct { p =>
p.typeclass.fromAny(v.get(p.index))(cm)
}
override def to(v: T)(cm: CaseMapper): GenericRecord =
caseClass.parameters.foldLeft(new GenericData.Record(schema(cm))) { (r, p) =>
r.put(p.index, p.typeclass.to(p.dereference(v))(cm))
r
}
}
}
}