Skip to content

Commit

Permalink
Update docs for new ways of using DSL
Browse files Browse the repository at this point in the history
  • Loading branch information
MateuszKubuszok committed Jan 5, 2025
1 parent 3ee9d8e commit f09a72d
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 14 deletions.
83 changes: 83 additions & 0 deletions docs/docs/supported-transformations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2917,6 +2917,37 @@ Or we might want to redirect two subtypes into the same target subtype. For that
// Bar(a = 10)
```

!!! notice

If one needs to handle this case in but nested inside a `case class`/`Option`/`Either`/collection, one can use
`.withFieldRenamed` with proper selectors:

```scala
//> using dep io.scalaland::chimney::{{ chimney_version() }}
//> using dep com.lihaoyi::pprint::{{ libraries.pprint }}
import io.scalaland.chimney.dsl._

sealed trait Source
object Source {
case object Foo extends Source
case class Baz(a: Int) extends Source
}

sealed trait Target
object Target {
case object Foo extends Target
case class Bar(a: Int) extends Target
}

pprint.pprintln(
List(Source.Baz(10): Source).into[List[Target]]
.withFieldRenamed(_.everyItem.matching[Source.Baz], _.everyItem.matching[Target.Bar])
.transform
)
// expected output:
// List(Bar(a = 10))
```

!!! notice

While `sealed` hierarchies, Scala 3 `enum`s and Java `enum`s fall into the same category of Algebraic Data Types,
Expand Down Expand Up @@ -3081,6 +3112,55 @@ If the computation needs to allow failure, there is `.withSealedSubtypeHandledPa
// Right(value = Buzz)
```

!!! notice

If one needs to handle this case in but nested inside a `case class`/`Option`/`Either`/collection, one can use
`.withFieldComputedFrom`/`.withFieldComputedPartialFrom` with proper selectors:

```scala
//> using dep io.scalaland::chimney::{{ chimney_version() }}
//> using dep com.lihaoyi::pprint::{{ libraries.pprint }}
import io.scalaland.chimney.dsl._
import io.scalaland.chimney.partial

sealed trait Foo
object Foo {
case class Baz(a: String) extends Foo
case object Buzz extends Foo
}
sealed trait Bar
object Bar {
case class Baz(a: String) extends Bar
case object Fizz extends Bar
case object Buzz extends Bar
}

pprint.pprintln(
List(Bar.Baz("value"): Bar, Bar.Fizz: Bar, Bar.Buzz: Bar)
.into[List[Foo]]
.withFieldComputedFrom(_.everyItem.matching[Bar.Fizz.type])(_.everyItem, fizz => Foo.Baz(fizz.toString))
.transform
)
// expected output:
// List(Baz(a = "value"), Baz(a = "Fizz"), Buzz)

pprint.pprintln(
List(Bar.Baz("value"): Bar, Bar.Fizz: Bar, Bar.Buzz: Bar)
.intoPartial[List[Foo]]
.withFieldComputedPartialFrom(_.everyItem.matching[Bar.Fizz.type])(_.everyItem, fizz => partial.Result.fromEmpty)
.transform
.asEither
)
// expected output:
// Left(
// value = Errors(
// errors = NonEmptyErrorsChain(
// Error(message = EmptyValue, path = Path(elements = List(Index(index = 1))))
// )
// )
// )
```

!!! notice

While `sealed` hierarchies, Scala 3 `enum`s and Java `enum`s fall into the same category of Algebraic Data Types,
Expand Down Expand Up @@ -3325,6 +3405,9 @@ If the computation needs to allow failure, there is `.withSealedSubtypeHandledPa
}
```

If one needs to handle this case in but nested inside a `case class`/`Option`/`Either`/collection, one can use
`.withFieldRenamed` with a proper selectors:

### Customizing subtype name matching

Be default names are matched with a `String` equality - `Subtype` would be considered a match for another `Subtype`
Expand Down
22 changes: 8 additions & 14 deletions docs/docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,8 @@ Here are some features it shares with Chimney (Ducktape's code based on GitHub P
// )
```

Chimney doesn't allow handling sealed subtypes/enum cases when nested, and require using implicit `Transformer`
which would handle them as top level:
Chimney allows handling nested sealed subtypes/enum cases when by using
`.withFieldComputedFrom`/'.withFieldComputedPartial`/`.withFieldRenamed` using proper selectors:

```scala
// file: snippet.scala - part of Ductape counterpart 2
Expand Down Expand Up @@ -1191,23 +1191,17 @@ Here are some features it shares with Chimney (Ducktape's code based on GitHub P
)

import io.scalaland.chimney.dsl.*
import io.scalaland.chimney.Transformer

pprint.pprintln {
// There is no direct analogue to nested:
// Case.const(_.paymentMethods.element.at[wire.PaymentMethod.Transfer], domain.PaymentMethod.Cash)
// so this has to be handled "top level" by creating implicit/given.
given Transformer[wire.PaymentMethod, domain.PaymentMethod] = Transformer
.define[wire.PaymentMethod, domain.PaymentMethod]
.withEnumCaseHandled[wire.PaymentMethod.Transfer](_ => domain.PaymentMethod.Cash)
.buildTransformer

pprint.pprintln(
wirePerson
.into[domain.Person]
.withFieldConst(_.firstName, "Jane")
// implicit instead of nested handling for withEnumCaseHandled
.withFieldComputedFrom(_.paymentMethods.everyItem.matching[wire.PaymentMethod.Transfer])(
_.paymentMethods.everyItem,
_ => domain.PaymentMethod.Cash
)
.transform
}
)
// expected output:
// Person(
// firstName = "Jane",
Expand Down

0 comments on commit f09a72d

Please sign in to comment.