Sometimes you might want to compare some nested values using a different comparator but the type they share is not unique within that hierarchy.
Consider following example:
import com.softwaremill.diffx._ import com.softwaremill.diffx.generic.auto._ case class Person(age: Int, weight: Int)
If we would like to compare
weight differently than
age we would have to introduce a new type for
in order to provide a different
Diff typeclass for only that field. While in general, it is a good idea to have your types
very precise it might not always be practical or even possible. Fortunately, diffx comes with a mechanism which allows
the replacement of nested diff instances.
First we need to acquire a lens at given path using
and then we can call
setTo to replace a particular instance.
implicit val diffPerson: Diff[Person] = Diff.summon[Person].modify(_.weight) .setTo(Diff.approximate(epsilon=5))
compare(Person(23, 60), Person(23, 62)) // res0: DiffResult = DiffResultObject( // name = "Person", // fields = ListMap( // "age" -> IdenticalValue(value = 23), // "weight" -> IdenticalValue(value = 60) // ) // )
In fact, replacement is so powerful that ignoring is implemented as a replacement
Specify how objects within particular collection within particular diff instance should be matched. We distinguish free main types of collections:
seqLike collections where elements are indexed collections
setLike collections where elements aren’t indexed
mapLike collections where elements(values) are indexed by some keys
Each collection should fall into one of above categories. Each category exposes different set of methods.
case class Organization(peopleList: List[Person], peopleSet: Set[Person], peopleMap: Map[Person, Person]) implicit val diffOrg: Diff[Organization] = Diff.summon[Organization] // seqLike methods: .modify(_.peopleList).matchByValue(_.age) .modify(_.peopleList).matchByIndex(index => index % 2) // setLike methods: .modify(_.peopleSet).matchBy(_.age) // mapLike methods: .modify(_.peopleMap).matchByValue(_.age) .modify(_.peopleMap).matchByKey(_.weight)