-
Notifications
You must be signed in to change notification settings - Fork 15
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
Introduce schema comparison #82
Conversation
src/main/scala/higherkindness/skeuomorph/mu/comparison/ComparisonResult.scala
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments. They're mostly related to naming. Apart of them, this looks awesome, thank you very much @vil1 !
|
||
sealed trait Transformation[T] | ||
|
||
object Transformation { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would name all cases of this ADT using nouns:
sealed trait Transformation[T] | ||
|
||
object Transformation { | ||
final case class NumericWiddening[T](relativePath: Path, from: T, to: T) extends Transformation[T] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final case class NumericWiddening[T](relativePath: Path, from: T, to: T) extends Transformation[T] | |
final case class NumericWidening[T](relativePath: Path, from: T, to: T) extends Transformation[T] |
final case class MadeOptional[T](relativePath: Path) extends Transformation[T] | ||
final case class PromotedToEither[T](relativePath: Path, either: T) extends Transformation[T] | ||
final case class PromotedToCoproduct[T](relativePath: Path, coproduct: T) extends Transformation[T] | ||
final case class CoproductWiddening[T](relativePath: Path, coproduct: T) extends Transformation[T] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final case class CoproductWiddening[T](relativePath: Path, coproduct: T) extends Transformation[T] | |
final case class CoproductWidening[T](relativePath: Path, coproduct: T) extends Transformation[T] |
final case class Addition[T](relativePath: Path, added: T) extends Transformation[T] | ||
final case class Removal[T](relativePath: Path, removed: T) extends Transformation[T] | ||
final case class MadeOptional[T](relativePath: Path) extends Transformation[T] | ||
final case class PromotedToEither[T](relativePath: Path, either: T) extends Transformation[T] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final case class PromotedToEither[T](relativePath: Path, either: T) extends Transformation[T] | |
final case class EitherPromotion[T](relativePath: Path, either: T) extends Transformation[T] |
final case class Removal[T](relativePath: Path, removed: T) extends Transformation[T] | ||
final case class MadeOptional[T](relativePath: Path) extends Transformation[T] | ||
final case class PromotedToEither[T](relativePath: Path, either: T) extends Transformation[T] | ||
final case class PromotedToCoproduct[T](relativePath: Path, coproduct: T) extends Transformation[T] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final case class PromotedToCoproduct[T](relativePath: Path, coproduct: T) extends Transformation[T] | |
final case class CoproductPromotion[T](relativePath: Path, coproduct: T) extends Transformation[T] |
import cats.Show | ||
import cats.syntax.show._ | ||
|
||
sealed trait Transformation[T] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that all the Transformation[T]
classes have a relativePath
field, I wonder if we can split them in two classes:
final case class At[T](relativePath: Path, transformation: Transformation[T])
sealed trait Transformation[T]
final case class NumericWidening[T](from: T, to: T) extends Transformation[T]
final case class StringConversion[T](rfrom: T, to: T) extends Transformation[T]
final case class Addition[T](added: T) extends Transformation[T]
final case class Removal[T](removed: T) extends Transformation[T]
final case class PromotionToOption[T]() extends Transformation[T]
final case class PromotionToEither[T](either: T) extends Transformation[T]
final case class PromotionToCoproduct[T](coproduct: T) extends Transformation[T]
final case class CoproductWidening[T](coproduct: T) extends Transformation[T]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be better now
case (TCoproduct(i), TCoproduct(i2)) => | ||
AlignUnionMembers( | ||
i.zipWithIndex | ||
.map { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to trim down the complexity for this case (essentially MxN cases), perhaps we could add a quick "canFit" predicate, one which would approximate the full "is compatible" case. Approximate, in this case, would mean that if canFit(p._1, p._2)
is false, that implies that p._1
cannot be compatible with p._2
. The benefit of course would be that canFit
would only look at the top level (not recursive).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this must indeed be addressed, but should be in another PR.
Beside the approach you suggest, we should be able to avoid a whole bunch of unnecessary comparison by making the traversal monadic (hyloM
) or using another scheme (maybe apo
but I'm not completely sure about that).
This PR introduces a mechanism for comparing two schemas.
Schemas are compared asymmetrically: one is considered the "writer" and the other the "reader". The comparison builds a result that can be either:
Match
with a (possibly empty) list of compatible transformations fromwriter
toreader
Mismatch
with also a list of compatibility violationsA compatible transformation is a difference between
writer
andreader
such that message written usingwriter
remain compatible withreader
.In a first iteration, I've decided to remain as close as possible to avro's spec in the set of accepted transformations. More might be implemented later.