mercredi 28 juillet 2021

How to automaticaly apply modifications to all/some fields of a case class in scala?

I'm currently challenging myself to skill up in Scala and FP. And today:

  • I came up with an issue that might interest you, devil prog masters ;)

Let's say I have the following case class in scala 3:

type EmailAddress = String // I defined them like that to show I'm interested in
type PhoneNumber = String // ... attributes via their names, not via their types.
case class Person(name: String, emails: List[EmailAddress], phones: List[PhoneNumber])

I would like to have a method that automatically transform (almost) all fields. For example, I would like to order emails with the default given instance of Ordering[String] and phones with a specified one. Ideally I should be able to exclude name field.

So I would get something like:

/* Below, I represented the kind of parametrization I would like to be able to do 
 * as parameters of the method orderValues,
 * but it could be annotations or meta-programming instead.
 * 
 * An `orderedPerson` can be directly an instance of Person
 * or something else like an OderedEntity[Person], I don't care so far.
 */
val orderedPerson =
  person.orderValues(
    excluded = Set("name"),
    explicitRules = Map(
      // Phones would have a special ordering (reverse is just a dummy value)
      "phones" -> Ordering.String.reverse
    )
  )

// -----

// So we would get:
Person(
  name = "Xiao",
  emails = List("a@a.a", "a@a.b", "a@b.a"),
  phones = List("+86 100 9000 1000", "+86 100 2000 1000")
)

I haven't used Reflection for a long time and I'm not yet familiar with Meta-Programming, but I'm open to any solution that can help me to achieve that. It's a good opportunity for learning !





Aucun commentaire:

Enregistrer un commentaire