Skip to content
Scala library for boilerplate-free, type-safe data transformations
Scala Shell
Branch: master
Clone or download
ldrygala missing test for automatic Unit parameter filling (#142)
* missing test for automatic Unit parameter filling

* conflicting name test

* identity transformer test for unit

* reformat

* avoid `pure expression does nothing in statement position`
Latest commit 43b86c1 Feb 4, 2020
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github Eliminate local TransformerDefinition allocation in code generation w… Jan 31, 2020
chimney/src
project bump scalafmt to 2.3.0 Jan 22, 2020
protos/src/test/scala
readme automatic filling of Unit parameters (#141) Feb 3, 2020
.gitignore ignore vscode project files (metals, bloop) Jan 21, 2020
.scalafmt.conf
LICENSE
README.md GH Actions status badge Feb 2, 2020
build.sbt
chimney.png
try-chimney.sh

README.md

Chimney Chimney logo

CI build Maven Central Javadocs codecov.io License Join the chat at https://gitter.im/scalalandio/chimney Scala.js

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.4.1"

Library is released for Scala 2.11.x, 2.12.x and 2.13.x.

If you want to use it with Scala.js (or Scala Native), 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

Thanks

Thanks to JProfiler (Java profiler) for helping us develop the library and allowing us to use it during development.

You can’t perform that action at this time.