Open kubukoz opened 6 months ago
Made some progress with @Baccata.
I won't write down the exact encoding just yet (I changed my mind several times in the last couple hours), but it appears that we'll draw a lot of inspiration from Contraband, including a @since("1.0")
trait (or similar) to allow marking new members as having been added in a particular version.
If there's a bunch of versions, we can generate a constructor / apply
for each of them, e.g.
//assume everything is required
structure Foo {
s1: String
@since("1.0") s2: String = "test2"
@since("1.0") s3: String = "test3"
s4: String
}
// we can add these traits for external shapes too, with `apply`
apply Foo$s4 @since("2.0")
apply Foo$s4 @default("test4")
final case class Foo private(s1: String, s2: String, s3: String, s4: String) { ... }
object Foo {
def apply(s1: String): Foo = new Foo(s1, "test2", "test3", "test4")
def apply(s1: String, s2: String, s3: String): Foo = new Foo(s1, s2, s3, "test4")
def apply(s1: String, s2: String, s3: String, s4: String) = new Foo(s1, s2, s3, s4)
}
I'll play with Contraband soon to see if it does this (and other interesting cases it handles, such as adding new values between existing ones) and get back with an update.
Related: https://github.com/disneystreaming/smithy4s/pull/1485, https://github.com/smithy-lang/smithy/issues/2243, Discord discussion
In some situations, such as generating protocol shapes (not limited to, but in particular: traits), it would be beneficial to allow evolving models without breaking binary compatibility of generated code.
For example, adding a new field to a struct trait shouldn't break binary compatibility of the result.
We should come up with and agree on:
withX
(for a member namedx
) instead of copy methodsand implement these for the next minor version (0.19), if possible.