Skip to content

Commit

Permalink
Add goals-and-non-goals section, improve TOC in troubeshootings, fix …
Browse files Browse the repository at this point in the history
…a few errors in docs
  • Loading branch information
MateuszKubuszok committed Nov 6, 2023
1 parent 7507cff commit 87a2e7f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
10 changes: 5 additions & 5 deletions docs/docs/supported-transformations.md
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ We are also able to provide values in nested structure:
.withFieldRenamed(_.foo, _.bar)
.withFieldConst(_.bar.c, 1000L)
.transform.asEither // Right(NestedBar(Bar("value", 1248, 1000L)))
```
```

### Wiring the constructor's parameter to the computed value

Expand Down Expand Up @@ -1075,7 +1075,7 @@ The requirements to use a value computation are as follows:
setters are enabled)

The last conditions is always met when working with `case class`es with no `private val`s in constructor, and classes
with all arguments declared as public `val`s, and Java Beans where each setter has corresponding getter defined.
with all arguments declared as public `val`s, and Java Beans where each setter has a corresponding getter defined.

!!! example

Expand Down Expand Up @@ -1222,8 +1222,8 @@ as transparent, similarly to virtually every other Scala library.

!!! warning

If you use any override (`withFieldConst`) getting value from/to `AnyVal`, it _will_ be treated as just a normal
product type.
If you use any value override (`withFieldConst`, `withFieldComputed`, etc.) getting value from/to `AnyVal`, it
_will_ be treated as just a normal product type.

## Between `sealed`/`enum`s

Expand Down Expand Up @@ -1778,7 +1778,7 @@ or having type parameter being not used at all:
Foo[AbstractType1]("value").transformInto[Bar[AbstractType2]] // Bar[AbstractType2]("value")
```

If the type is `abstract`, used as a value, but contains enough information that one of existing rules
If the type is `abstract` and used as a value, but contains enough information that one of existing rules
knows how to apply it, the transformation can still be derived:

!!! example
Expand Down
56 changes: 46 additions & 10 deletions docs/docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@

Already using Chimney and you've got some issues? This page might help you with it.

## Goals and non-goals

While Chimney is usually used to convert one piece of immutable data into another piece of immutable data, not every
time you are working with immutable values you need Chimney.

The main goal of Chimney is minimizing the amount of code you have to write to convert a value of one type (known at
compile time) into a value of another type (also known at compile time). While there are Patchers, their goal is to
update one value, using another value and nothing more.

If you:

- receive some unstructured, raw input value (String, InputStream, binary data, ...) you are not looking for Chimney
when it comes to parsing it - you need a parser library. Maybe it will be a JSON parser, or something you could
build with parser combinators, or a code generated with Interface Description Language (IDL) like Protocol Buffers,
Swagger or AsyncAPI.
- However, if you parse raw data into some structured data, that structured data can be used by Chimney to convert
into e.g. domain model
- want to update immutable data by passing some path to the updated field and then provide a value - you need a lens
library like Quicklens or Monocle
- want to limit the amount of tests written and are wondering if automatic generation of such an important code is
safe - you need to ask yourself: would you have the same dilemma if you were asked about generating JSON codecs?
Would you wonder if you need to test them? (In our experience, yes). Could you remove the need to test them if you
mandated the code to be always/never generated? (In our experience, whether its generated or written by hand you
want to test it).
- You can however avoid testing someone else's library if you use Chimney in place, in some service, and then test
that service's behavior or if you create in your DTO model `def toDomain = this.transformInto[DomainModel]`.
You can utilize code generation without making your application's type signatures depend on someone else's types.

## Migration from 0.7.x to 0.8.0

Version 0.8.0 is the first version that cleaned up the API. It introduced several breaking changes.
Expand Down Expand Up @@ -220,7 +248,15 @@ if there is no source field nor other fallback or override. Although it is
a bugfix, it is also a breaking change so it has to be documented. The fix would
be a manual resolution for all fields which now (correctly) fail due to the bugfix.

## Recursive types fail to compile
## Compilation errors

When some transformation cannot be generated with the information available to the library, it is perfectly normal that
a macro would generate a compilation error with a message describing the issue.

However, some compilation errors might seem unreasonable as everything seems to be configured correctly for a use case
that is officially supported.

### Recursive types fail to compile

Chimney attempts to avoid unnecessary memory allocations for good performance.

Expand Down Expand Up @@ -254,7 +290,7 @@ and then

The same is true for partial transformers.

## Recursive calls on implicits
### Recursive calls on implicits

Old versions of Chimney in situations like this:

Expand Down Expand Up @@ -290,7 +326,7 @@ It's a sign of recursion which has to be handled with [semiautomatic derivation]
implicit val t: Transformer[Foo, Bar] = Transformer.define[Foo, Bar].buildTransformer
```

## `sealed trait`s fail to recompile
### `sealed trait`s fail to recompile

In the case of incremental compilation, the Zinc compiler sometimes has issues with
caching certain kind of information and macros don't get proper information
Expand All @@ -301,7 +337,7 @@ the compiler to provide it with this data, and the compiler fails to do so.
On Scala 2.12.0 it failed [in other cases as well (scala/bug#7046)](https://github.com/scala/bug/issues/7046),
so it is recommended to update 2.12 to at least 2.12.1.

## Scala 3 complains that `implicit`/`given` `TransformerConfiguration` needs an explicit return type
### Scala 3 complains that `implicit`/`given` `TransformerConfiguration` needs an explicit return type

In Scala 2 syntax like

Expand Down Expand Up @@ -336,7 +372,7 @@ You can work around this by slightly longer incantation:
TransformerConfiguration.default.enableMacrosLogging
```

## `java.lang.UnsupportedOperationException: Position.point on NoPosition` error
### `java.lang.UnsupportedOperationException: Position.point on NoPosition` error

On Scala 2 `java.lang.UnsupportedOperationException: Position.point on NoPosition` is most commonly seen due to
[scala/bug#10604](https://github.com/scala/bug/issues/10604) - when JVM used for compilation has a small stack trace
Expand All @@ -350,7 +386,7 @@ However, if you are using the compiler's flags to report unused definitions when
an error caused by [scala/bug#12895](https://github.com/scala/bug/issues/12895). In such case the workaround would be to
remove the unused definition reporting.

## Debugging macros
### Debugging macros

In some cases, it could be helpful to preview what is the expression generated
by macros, which implicits were used in macro (or not) and what was the exact
Expand Down Expand Up @@ -583,10 +619,10 @@ would generate:
+ Rule Subtypes expanded successfully: userupdateform.phone
+ Derived recursively total expression userupdateform.phone
+ Rule TypeToValueClass expanded successfully: new Phone(userupdateform.phone)
+ Derived final expression is:
| new User(user.id, new Email(userupdateform.email), new Phone(userupdateform.phone))
+ Derivation took 0.028971000 s
```
+ Derived final expression is:
| new User(user.id, new Email(userupdateform.email), new Phone(userupdateform.phone))
+ Derivation took 0.113354000 s
```

## Ideas, questions or bug reports

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/under-the-hood.md
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ Chimney would have specialized expression generation for things like:
these collections to accumulate errors and add indices/keys to the error information

For each of these `Rule` might decide whether the case should be handled. Some of these rules needs to be tested before
some other rules (e.g. there might be several `Rule`s for `AnyVal`s with specific order) and have no requirements about
some other rules (e.g. there might be several `Rule`s for `AnyVal`s with a specific order) and have no requirements about
other rules (e.g. `Rule`s handling `Option`s might be unrelated to `Rule`s handling `AnyVal`s and not affect each other).

#### Product types
Expand Down

0 comments on commit 87a2e7f

Please sign in to comment.