/claim #519 /closes #519
Both Scala 2 and Scala 3 have compile time validation. They extract the ShapeTree of SchemaA and SchemaB, and do a Tree.diff which returns added and removed, of the form List[List[Segement]]
private[migration] object Segment {
case class Field(name: String) extends Segment
case class Case(name: String) extends Segment
case object Element extends Segment
case object Key extends Segment
case object Value extends Segment
case object Wrapped extends Segment
}
When .build is run, as we go through MigrationAction, each migration action collects Handled and Provided, which is also of the form List[List[Segement]] , which are then compared against added and removed. On success we compile.
Example of List[List[Segement]] : List((Field("address"), Field("city")), Field("age")) -> It has two path address.city and age.
Note - This is a different List of Lists, rather than encoding level and field. I though having a clear path to the field which was added or removed was a better decision.
Support for Selector Syntax for _.field, _.nested.field, _.case.when[Batman]. _.field.each. Also includes support for bare Literal SchemaExpr, so it is easier to write migration code.
_.address.street + _.address.city → _.address.fullAddress -> this is done
_.address.street + _.origin.country → _.address.fullAddress -> This gets complex since now we have to extract values from multiple nested source paths, combine to targeted nested path, remove the nested source fields, and rebuilt the whole structure immutability.
So if the parent is not the same, it gracefully errors out at both runtime (if .buildpartial was used) and during compile validation (if .build was used)
Added Serialization - Using a new DynamicSchemaExpr a serializable version of SchemaExpr . Manually derived schema for all things which make up DynamicMigration
final case class SchemaExpr[A, B](
dynamic: DynamicSchemaExpr,
inputSchema: Schema[A],
outputSchema: Schema[B]
)
Added Structural tests, to showcase the structural can be migrated properly. Deviation is they are not supported via compile time validation. During .build they fall through and are parsed as a PrimitiveNode. All the tests currently used .buildPartial. Maybe fixable by adding a check to see if they are refinement type and exploring their structure at compile time in both 2 and 3.
Ajay RV
@Nanashi-lab
marianaguzmanguerrero16-dev
@marianaguzmanguerrero16-dev
ZIO
@ZIO