case class Source(a: Int, b: String, c: Boolean)
case class Target(b: String, a: Int)
import io.scalaland.chimney.dsl.*
Source(777, "value", c = true).transformInto[Target]
// Target("value", 777)
Translating between layers with Chimney
Mateusz Kubuszok
breaking things in Scala for 9 years
a little bit of open source - including co-authoring Chimney for almost 7 years now
blog at Kubuszok.com
niche Things you need to know about JVM (that matter in Scala) ebook
simple web backend
Circe codecs
Doobie (well, Slick actually)
Protobuf and Kinesis (well, it was Avro and Postgres)
Let’s look at example
It kinds works, but let add a few modifications:
for creationDate
let’s use Instant`
for id
let’s use UUID
We can still improve it!
let’s create a separate model for JSONs
let’s create a separate model for DB operations
Could we get rid of the silly code for mapping?
YES
case class Source(a: Int, b: String, c: Boolean)
case class Target(b: String, a: Int)
import io.scalaland.chimney.dsl.*
Source(777, "value", c = true).transformInto[Target]
// Target("value", 777)
case class Source(a: Int, b: String)
case class Target2(b: String, a: Int, extra: Double)
import io.scalaland.chimney.dsl.*
Source(777, "value").into[Target2]
.withFieldConst(_.extra, 3.14)
.transform // Target2("value", 777, 3.14)
Source(777, "value").into[Target2]
.withFieldComputed(_.extra, src => src.a.toDouble)
.transform // Target2("value", 777, 777.0)
enum Source:
case Foo, Bar(b: Int)
enum Target:
case Foo, Bar(b: Int), Baz
import io.scalaland.chimney.dsl.*
(Source.Bar(777): Source).transformInto[Target]
// Target.Bar(777)
enum Source:
case Foo, Bar(b: Int), Baz
enum Target:
case Foo, Bar(b: Int)
import io.scalaland.chimney.dsl.*
(Source.Baz: Source).into[Target]
.withEnumCaseHandled[Source.Baz](_ => Target.Foo)
.transform // Target.Foo
case class Source(a: Int, b: String, c: Boolean)
case class Target(b: String, a: Int)
import io.scalaland.chimney.dsl.*
List(Source(777, "value")).transformInto[Vector[Target]]
// Vector(Target("value", 777))
case class Source(a: Int, b: String)
case class Target2(b: String, a: Int, extra: Double)
import io.scalaland.chimney.dsl.*
List(Source(777, "value")).into[Vector[Target]]
.withFieldConst(_.eachItem.extra, 3.14)
.transform // Vector(Target("value", 777, 3.14))