All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mthaler.replica.Replicator.scala Maven / Gradle / Ivy

The newest version!
package com.mthaler.replica

object Replicator {

  /**
   * Copies a case class replacing values with updated values
   *
   * @param t case class
   * @param updated map containing updated values
   * @tparam T
   * @return copy of case class with updated values
   */
  def copy[T <: Product](t: T, updated: Map[String, Any] = Map.empty[String, Any]): T = {
    // create list of values of the class
    val values = t.productIterator.toList.map(_.asInstanceOf[AnyRef])
    val clazz = t.getClass
    // create list of fields of the class
    val fields = clazz.getDeclaredFields.toList
    // unwrap value classes
    val unwrapped = for ((field, value) <- fields.zip(values)) yield if (field.getType != value.getClass) unwrap(value).asInstanceOf[AnyRef] else value
    val fieldNames = fields.map(_.getName)
    val newValues = for ((field, value) <- fieldNames zip unwrapped) yield if (updated.contains(field)) updated(field).asInstanceOf[AnyRef] else value
    val result = clazz.getConstructors.head.newInstance(newValues: _*).asInstanceOf[T]
    result
  }

  private[replica] def unwrap(value: Any): Any = {
    val clazz = value.getClass
    val fields = clazz.getDeclaredFields.toList
    if (fields.size == 1) {
      val f = fields.head
      f.setAccessible(true)
      f.get(value)
    } else {
      value
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy