Skip to content

Commit 354ee9e

Browse files
committed
chimney
1 parent eb8d65a commit 354ee9e

File tree

6 files changed

+164
-0
lines changed

6 files changed

+164
-0
lines changed

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ lazy val scala_libraries = (project in file("scala-libraries"))
445445
"org.elasticmq" %% "elasticmq-rest-sqs" % "1.6.7",
446446
"software.amazon.awssdk" % "sqs" % "2.27.10"
447447
),
448+
libraryDependencies += "io.scalaland" %% "chimney" % "1.4.0",
448449
Defaults.itSettings
449450
)
450451

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.baeldung.chimney
2+
3+
import io.scalaland.chimney.*, dsl.*, partial.*
4+
5+
object ChimneyCodec extends App:
6+
7+
case class Domain(a: Int, b: String)
8+
case class Dto(b: Option[String], a: Option[Int])
9+
10+
given Codec[Domain, Dto] = Codec.derive
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.baeldung.chimney
2+
3+
import io.scalaland.chimney.*, dsl.*, partial.*
4+
5+
object ChimneyIso extends App:
6+
7+
case class StructuredItem(uuid: java.util.UUID)
8+
case class DomainItem(uuid: java.util.UUID)
9+
10+
given Iso[StructuredItem, DomainItem] = Iso.derive
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.baeldung.chimney
2+
3+
import io.scalaland.chimney.*, dsl.*, partial.*
4+
5+
object ChimneyPartialTransformer extends App:
6+
7+
val fn: Int => Boolean =
8+
case 0 => false
9+
case 1 => true
10+
case i => throw Exception(s"Provided integer invalid: $i")
11+
12+
given PartialTransformer[Int, Boolean] =
13+
PartialTransformer.fromFunction(fn)
14+
15+
val result: Result[Boolean] = 0.transformIntoPartial[Boolean]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.baeldung.chimney
2+
3+
import io.scalaland.chimney.dsl.*
4+
5+
object ChimneyPatcher extends App:
6+
7+
case class User(id: Int, email: Option[String], phone: Option[Long])
8+
9+
case class UserUpdateForm(email: String, phone: Long)
10+
11+
val user = User(10, Some("abc@@domain.com"), Some(1234567890L))
12+
val updateForm = UserUpdateForm("xyz@@domain.com", 123123123L)
13+
14+
val patchedValue: User = user.patchUsing(updateForm)
15+
16+
// Standard Library Alternative
17+
18+
case class SimpleCaseClass(a: Int, b: Int)
19+
20+
val simpleClass = SimpleCaseClass(0, 0)
21+
22+
simpleClass.copy(b = 2) // SimpleCaseClass(0, 2)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.baeldung.chimney
2+
3+
import io.scalaland.chimney.*, dsl.*, partial.*
4+
5+
object ChimneyTransformers extends App:
6+
7+
class MyType(val a: Int)
8+
9+
class MyOtherType(val b: String):
10+
override def toString: String = s"MyOtherType($b)"
11+
12+
val transformer: Transformer[MyType, MyOtherType] = (src: MyType) =>
13+
new MyOtherType(src.a.toString)
14+
15+
transformer.transform(new MyType(10)) // new MyOtherType("10")
16+
17+
implicit val transformerAsImplicit: Transformer[MyType, MyOtherType] =
18+
transformer
19+
20+
(new MyType(10)).transformInto[MyOtherType]
21+
22+
// Transitive Given Instances
23+
24+
trait Serial[T]:
25+
def serial(v: T): String
26+
27+
given Serial[MyOtherType] with
28+
def serial(v: MyOtherType): String = v.toString
29+
30+
given [F, T](using Serial[T], Transformer[F, T]): Serial[F] with
31+
def serial(v: F): String =
32+
summon[Serial[T]].serial:
33+
summon[Transformer[F, T]].transform(v)
34+
35+
// Automatic Case Class Transformation
36+
37+
// UserDTO
38+
39+
case class UserDTO(
40+
name: String, // 1. primitive
41+
addresses: Seq[AddressDTO], // 2. Seq collection
42+
recovery: Option[RecoveryMethodDTO] // 3. Option type
43+
)
44+
45+
case class AddressDTO(street: String, city: String)
46+
47+
sealed trait RecoveryMethodDTO
48+
49+
object RecoveryMethodDTO:
50+
case class Phone(value: PhoneDTO) extends RecoveryMethodDTO
51+
case class Email(value: EmailDTO) extends RecoveryMethodDTO
52+
53+
case class PhoneDTO(number: String)
54+
case class EmailDTO(email: String)
55+
56+
// User Domain Model
57+
58+
case class User(
59+
name: Username,
60+
addresses: List[Address],
61+
recovery: RecoveryMethod
62+
)
63+
64+
case class Username(name: String) extends AnyVal
65+
case class Address(street: String, city: String)
66+
67+
enum RecoveryMethod:
68+
case Phone(number: String)
69+
case Email(email: String)
70+
71+
// we can do a transformation:
72+
73+
User(
74+
Username("John"),
75+
List(Address("Paper St", "Somewhere")),
76+
RecoveryMethod.Email("[email protected]")
77+
).transformInto[UserDTO]
78+
79+
// Standard Library alternatives
80+
81+
// Selectable
82+
83+
class Record(elems: (String, Any)*) extends Selectable:
84+
private val fields = elems.toMap
85+
def selectDynamic(name: String): Any = fields(name)
86+
87+
type Person = Record {
88+
val name: String
89+
val age: Int
90+
}
91+
92+
val person = Record(
93+
"name" -> "Emma",
94+
"age" -> 42
95+
).asInstanceOf[Person]
96+
97+
// Tuple Generics
98+
99+
case class Employee(name: String, number: Int, manager: Boolean)
100+
101+
val bob: Employee = Employee("Bob", 42, false)
102+
103+
val bobTuple: (String, Int, Boolean) = Tuple.fromProductTyped(bob)
104+
105+
val bobAgain: Employee =
106+
summon[deriving.Mirror.Of[Employee]].fromProduct(bobTuple)

0 commit comments

Comments
 (0)