Scala Shell
Clone or download
asdcdow and krzemin Fixes #67: Support any class as source as long as target is a case cl…
…ass (#70)

* Fixes #67: Support any class as source as long as target is a case class

* Fix scalafmt issues
Latest commit f6f0844 Jul 23, 2018

README.md

Chimney Chimney logo

Build Status Maven Central Javadocs codecov.io License

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")
val event = CoffeeMade(id = command.id,
                       kind = command.kind,
                       forAddict = command.addict,
                       at = ZonedDateTime.now)

While the example stays lean, 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

Underneath it uses Scala macros to give you:

  • type-safety at compile-time
  • fast generated code, almost equivalent to hand-written version
  • excellent error messages
  • minimal overhead on compilation time

Getting started

To include Chimney to your SBT project, add the following line to your build.sbt:

libraryDependencies += "io.scalaland" %% "chimney" % "0.2.1"

Library is released for Scala 2.11 and 2.12. If you want to use it with Scala.js, you need to replace %% with %%%. Due to some compiler bugs, it's recommended to use at least Scala 2.11.9 or 2.12.1.

Trying with Ammonite REPL

The quickest way to try out Chimney is to use a script that downloads coursier and uses it to fetch Ammonite REPL with the latest version of Chimney. It drops you immediately into a REPL session.

curl -s https://raw.githubusercontent.com/scalalandio/chimney/master/try-chimney.sh | bash
Loading...
Welcome to the Ammonite Repl 1.1.0
(Scala 2.12.4 Java 1.8.0_152)
If you like Ammonite, please support our development at www.patreon.com/lihaoyi
@ case class Foo(x: String, y: Int) 
defined class Foo

@ case class Bar(x: String, y: Int, z: Boolean = true) 
defined class Bar

@ Foo("abc", 10).transformInto[Bar] 
res2: Bar = Bar("abc", 10, true)

Documentation

Chimney documentation is available at https://scalalandio.github.io/chimney