-
-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
patcher does not distinguish between case class parameters and fields since 0.8.x #414
Comments
TBH, IMHO the previous behavior is a bug, and we haven't caught it before since there was no test which used Patchers that way. As far as our tests were concerned (in 0.7.5) using In future, we plan to implement case class merging, and rewrite |
i'd argue vals defined in a class body should be ignored in general as they rather contain domain specifics which should not be accounted for in transformations (that's the unintentional 0.7.5 behavior) furthermore to me it seems there's already a difference in transformer and patcher behavior, e.g.: https://scastie.scala-lang.org/Dbf0kkhVQPOuhBbochlsww we have pretty much the same use case in our code base. two case classes have exactly the same constructor parameter val definitions, but both also define a class body val with the same name. in this case we can't transform between those two (as a workaround we could add .ignoreRedundantPatcherFields but then we loose that important check for the constructor parameters) |
I agree, there are mismatches between Patchers and Transformers. But the only intended difference is that:
Everything else is an accidental consequence of the fact that the current implementations of Patchers was merely put together in a quick-and-dirty way import io.scalaland.chimney.dsl._
case class A(i: Int) {
val b: Boolean = false
}
case class B(i: Int) {
val b: Boolean = false
}
A(0).transformInto[B] // compiles
A(0).using(new { val i = 1 }).patch // <------ also compiles (*)
A(0).using(B(1)).ignoreRedundantPatcherFields.patch // compiles
// (*) I guess on Scala 3 I could get away with:
// val patch = B(1)
// new { export patch.i } or
// new { export patch.{b => _, *} } or
// new { export patch.{b as i} } + given Transformer[Boolean, Int]
// etc, depending on what I need (see Scastie) and write unit tests checking if the runtime value is as I would expect it to be. And if that doesn't look super useful... Well, TBH I myself see current
I'd say that currently Patchers are designed mostly for cases when you define
That was intentional behavior that we tested for since class Foo {
val a: Int = 42
}
case class Bar(a: Int)
(new Foo).transformInto[Bar] for quite a while. The main difference in 0.8.0 is that we relaxed requirements on target from " |
We find patchers still very useful (applying an Event as a patch on top of a State in EventSourcing) but I understand our use case is fairly specific. I guess we'll just add a Nevertheless, thanks @MateuszKubuszok for your fast and detailed reply! Really appreciate the time you take and thanks for creating and improving this great library :) |
No problem, hopefully, with Scala 3 and improvements we might pull off in the future |
Checklist
TransformerF
s) orunsafeOption
flagsDescribe the bug
Chimney 0.7.x ignored additional case class field variables on the source when using a patcher. It only complained about additional parameters. In chimney 0.8.x this has changed.
I've checked the release notes of 0.8.x and the migration guide but I couldn't find anything describing this breaking change. is this intentional?
Reproduction
0.7.5 compiles: https://scastie.scala-lang.org/DrVVl6FWSGKhev9hlbOViA
0.8.0 does not compile: https://scastie.scala-lang.org/DQ0iG1YsRIWw2GgfLKlRKA
The text was updated successfully, but these errors were encountered: