Chimney is a Scala library for boilerplate-free data transformations.

In the daily life of a strongly-typed language’s programmer sometimes it happens we need to transform an object of one type to another object which contains a number of the same or similar fields in their definitions.

case class MakeCoffee ( id : Int , kind : String , addict : String ) case class CoffeeMade ( id : Int , kind : String , forAddict : String , at : ZonedDateTime )

Usual approach is to just rewrite fields one by one

val command = MakeCoffee ( id = Random . nextInt , kind = "Espresso" , addict = "Piotr" ) // MakeCoffee(24, "Espresso", "Piotr") val event = CoffeeMade ( id = command . id , kind = command . kind , forAddict = command . addict , at = ZonedDateTime . now ) // CoffeeMade(24, "Espresso", "Piotr", "2020-02-03T20:26:59.659647+07:00[Asia/Bangkok]")

While the example stays short, in real-life code we usually end up with tons of such boilerplate, especially when:

we maintain typed schema and want to migrate between multiple schema versions

we apply practices like DDD (Domain-Driven-Design) where suggested approach is to separate model schemas of different bounded contexts

we use code-generation tools like Protocol Buffers that generate primitive types like Int or String , while you’d prefer to use value objects in you domain-level code to improve type-safety and readability

Chimney provides a compact DSL with which you can define transformation rules and transform your objects with as little boilerplate as possible.

import io.scalaland.chimney.dsl._ val event = command . into [ CoffeeMade ] . withFieldComputed ( _ . at , _ => ZonedDateTime . now ) . withFieldRenamed ( _ . addict , _ . forAddict ) . transform // CoffeeMade(24, "Espresso", "Piotr", "2020-02-03T20:26:59.659647+07:00[Asia/Bangkok]")

Read Getting started with transformers to learn more about Chimney’s transformers.