Skip to content

Commit

Permalink
Fix using of fieldName annotations to rename fields (not aliasing) (#773
Browse files Browse the repository at this point in the history
)
  • Loading branch information
plokhotnyuk authored Jan 9, 2025
1 parent 8e1c5fa commit d24ae5f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ private case class DeriveSchema()(using val ctx: Quotes) {
tpe.asType
}
val annotations = paramAnns.getOrElse(label, List.empty)
val nameExpr = annotations.collectFirst {
val nameExpr = annotations.reverse.collectFirst {
case ann if ann.isExprOf[fieldName] =>
val fieldNameAnn = ann.asExprOf[fieldName]
'{${fieldNameAnn}.name}
Expand Down Expand Up @@ -291,7 +291,7 @@ private case class DeriveSchema()(using val ctx: Quotes) {
tpe.asType
}
val annotations = paramAnns.getOrElse(label, List.empty)
val nameExpr = annotations.collectFirst {
val nameExpr = annotations.reverse.collectFirst {
case ann if ann.isExprOf[fieldName] =>
val fieldNameAnn = ann.asExprOf[fieldName]
'{${fieldNameAnn}.name}
Expand Down Expand Up @@ -478,7 +478,7 @@ private case class DeriveSchema()(using val ctx: Quotes) {
val chunk = '{ zio.Chunk.fromIterable(${ Expr.ofSeq(anns.reverse) }) }

if (anns.nonEmpty) {
val (newName, newNameValue) = anns.collectFirst {
val (newName, newNameValue) = anns.reverse.collectFirst {
case ann if ann.isExprOf[fieldName] =>
val fieldNameAnn = ann.asExprOf[fieldName]
('{${fieldNameAnn}.name}, extractFieldNameValue(fieldNameAnn))
Expand Down Expand Up @@ -529,7 +529,7 @@ private case class DeriveSchema()(using val ctx: Quotes) {
val chunk = '{ zio.Chunk.fromIterable(${ Expr.ofSeq(anns.reverse) }) }

if (anns.nonEmpty) {
val newName = anns.collectFirst {
val newName = anns.reverse.collectFirst {
case ann if ann.isExprOf[fieldName] => '{${ann.asExprOf[fieldName]}.name}
}.getOrElse(Expr(name))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,10 @@ object DeriveSchemaSpec extends ZIOSpecDefault with VersionSpecificDeriveSchemaS
implicit lazy val schema: Schema.EnumN[Enum23, CaseSet.Aux[Enum23]] = DeriveSchema.gen[Enum23]
}

case class RenamedField(@fieldName("renamed") name: String, @fieldName("number") num: Int)
case class RenamedField(
@fieldName("renamed") @fieldName("ignored_rename") name: String,
@fieldName("number") num: Int
)

object RenamedField {
implicit lazy val schema: Schema[RenamedField] = DeriveSchema.gen[RenamedField]
Expand Down Expand Up @@ -445,15 +448,17 @@ object DeriveSchemaSpec extends ZIOSpecDefault with VersionSpecificDeriveSchemaS
assert(Schema[ContainsSchema].toString)(not(containsString("null")) && not(equalTo("$Lazy$")))
},
test("correctly derives renaming field when fieldName annotation is present") {
val derived = DeriveSchema.gen[RenamedField]
val derived = DeriveSchema.gen[RenamedField]
val derivedField1 = derived.asInstanceOf[Schema.CaseClass2[String, Int, RenamedField]].field1
val derivedField2 = derived.asInstanceOf[Schema.CaseClass2[String, Int, RenamedField]].field2

val expected: Schema[RenamedField] = {
Schema.CaseClass2(
TypeId.parse("zio.schema.DeriveSchemaSpec.RenamedField"),
field01 = Schema.Field(
"renamed",
Schema.Primitive(StandardType.StringType),
Chunk(fieldName("renamed")),
Chunk(fieldName("renamed"), fieldName("ignored_rename")),
get0 = _.name,
set0 = (a, b: String) => a.copy(name = b)
),
Expand All @@ -467,6 +472,10 @@ object DeriveSchemaSpec extends ZIOSpecDefault with VersionSpecificDeriveSchemaS
RenamedField.apply
)
}
assert(derivedField1.fieldName)(equalTo("renamed")) &&
assert(derivedField1.nameAndAliases)(equalTo(Set("renamed"))) &&
assert(derivedField2.fieldName)(equalTo("number")) &&
assert(derivedField2.nameAndAliases)(equalTo(Set("number"))) &&
assert(derived)(hasSameSchema(expected)) &&
assert(verifyFieldName[derived.Field1]("renamed"))(isTrue)
},
Expand Down
14 changes: 8 additions & 6 deletions zio-schema/shared/src/main/scala/zio/schema/Schema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -432,16 +432,18 @@ object Schema extends SchemaPlatformSpecific with SchemaEquality {
val transient: Boolean =
annotations.exists(_.isInstanceOf[transientField])

val nameAndAliases: scala.collection.immutable.Set[String] =
annotations.collect {
case aliases: fieldNameAliases => aliases.aliases
case f: fieldName => Seq(f.name)
}.flatten.toSet + name

val fieldName: String = annotations.collectFirst {
case f: fieldName => f.name
}.getOrElse(name)

val nameAndAliases: scala.collection.immutable.Set[String] =
annotations.foldLeft(scala.collection.immutable.Set(fieldName)) { (acc, annotation) =>
annotation match {
case aliases: fieldNameAliases => acc ++ aliases.aliases
case _ => acc
}
}

override def toString: String = s"Field($name,$schema)"
}

Expand Down

0 comments on commit d24ae5f

Please sign in to comment.