chimney
chimney copied to clipboard
Support for mapping multiple case classes
Presuming I had the following:
case class Container1(a: Int)
case class Container2(b: String)
case class MergedContainers(a: Int, b: String)
It would be nice to do something like either of the following:
(Container1(1),Container2("HI")).transformInto[MergedContainers]
Or perhaps:
case class NestedContainers(container1: Container1, container2: Container2)
NestedContainers(Container1(1),Container2("HI")).transformInto[MergedContainers]
Having case class that combines containers (NestedContainer
), this should be also achievable by first proposal: https://github.com/scalalandio/chimney/issues/100#issuecomment-480563946
Do you think this will be implemented sometime soon? Had a need for it a few times and used hacks but I have a feeling I’ll have a blocker in the next month or two and this could really come in handy
@ittaiz many people ask for this feature recently - I think it should be next top priority. But it requires a lot of time to design it correctly, so I can't guarantee any fixed time frame.
Sure thing, I complete understand. I appreciate the intent and thank you for your work!
On Fri, 3 Apr 2020 at 19:14 Piotr Krzemiński [email protected] wrote:
@ittaiz https://github.com/ittaiz many people ask for this feature recently - I think it should be next top priority. But it requires a lot of time to design it correctly, so I can't guarantee any fixed time frame.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/scalalandio/chimney/issues/115#issuecomment-608530442, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKQQF4ILFPXGK4BBOMBDG3RKYDPNANCNFSM4IA5QDOQ .
Ah, yeah, this is the feature I've been looking for. I imagine it's on the hard side to implement. Many thanks for your work on chimney @MateuszKubuszok
I have some idea how to do it, but it will be a significant amount of work.
I was thinking about prioritizing 1.0.0-RC first, to not delay it anymore, and then( later in 2024) starting to work on such merging transformation (it would allow us to internally reimplement Patcher
s as such transformer). The challenges for this feature are that:
- it would have to merge values recursively because that's where lies its true usefulness
- it would have to allows merging and transforming an arbitrary number of values
- it would have to cooperate with all the existing overrides (
.withField*
,.enable*
) - it would have to preserve the semantics of existing code, and make sure that existing tests will still pass
I have some an idea how to do it, but it would require refactoring a few sensitive pieces of code, writing a bit more pieces of a new code, and creating a tons of tests to avoid feature interaction bugs, because at this point it's really easy to write code which might look okayish, pass a simple test, compile (obviously) but provide an unexpected behavior when combined with some other feature.
So I am planning to work on it somewhere in 2024, but I have no idea how much time I'll have so I am not committing to any ETA.
Yeah, I had gotten stuck on this issue about 4 years ago IIRC, and returned to the same problem recently. Below is my best effort to make something like this work today (leveraging some tools I'm sure you'd rather not add to chimney
, and losing some of chimney's cleverness about failed transforms).
import io.scalaland.chimney.dsl._
import org.scalacheck.ScalacheckShapeless._
import org.scalacheck.Arbitrary
case class X(a: Int)
case class Y(b: Int)
case class Z(a: Int, b: Int)
val x = X(1)
val y = Y(2)
val z = Arbitrary.arbitrary[Z]
.sample
.get
.patchUsing(x)
.patchUsing(y)