I'm trying to write a boilerplate function that can take a pair of generic case class objects and perform some operations on their set of val
s and then return a new instance of the case class.
On a more detailed level that is not the intended focus of this question, the operation I am performing is zipping the two two lists of vals and selectively deciding which item of the tuple is placed into the new instance by way of a List[Boolean] of flags that indicate the left or right object.
I have the majority of the concept written up, and to the best of my research so far my strategy is to convert the case class objects into a list of the vals (using Product.productIterator) and then eventually turn a list of vals into a tuple (SO reference) to feed into Function.tupled (SO reference) (which is available on case classes).
trait PermissionMask[B <: Product] {
val permissionMask: List[Boolean]
def mergePermissibleEdits(userObject: B, trustedObject: B) = {
val possibleValues = (userObject.productIterator.toList) zip (trustedObject.productIterator.toList)
val valuesWithFlags = possibleValues zip permissionMask
val mergedObjectList = valuesWithFlags map { case ((userValue, trustedValue), userEditable) => if (userEditable) userValue else trustedValue }
//TODO: Not possible, I don't have a direct reference to the case class since it's generic, not sure how to get the reference
B.tupled(mergedObjectList) //I have implicit conversions to tuple1-22 from list
}
}
If I wasn't using generics and knew the concrete case class, I could simply call SomeCaseClass.tupled(mergedObjectList). However, since it's generic I am fuzzy on how (if even possible) I can make that same call.