Skip to content
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

Patch value with Diff #81

Closed
thinkharderdev opened this issue Jun 18, 2021 · 3 comments
Closed

Patch value with Diff #81

thinkharderdev opened this issue Jun 18, 2021 · 3 comments
Labels
feature New library features good first issue Good for newcomers

Comments

@thinkharderdev
Copy link
Contributor

This is a placeholder to gather thoughts but the initial idea is to:

Once #78 is implemented, we can add a method to the Schema[A] trait:

trait Schema[A] { self =>
  def patch(diff: Diff): Either[String, A => Either[String,A]]
}

which returns a Left(error message) if the diff cannot be applied to the schema structure (e.g. if I try to apply a Diff.Number to a Schema.Record and otherwise returns a function which will apply the specified diff to value of type A (possibly failing).

And associated syntax

implicit class DiffOps[A: Schema](a: A) {
   def patch(diff): Either[String,A] = Schema[A].patch(diff).flatMap(_.apply(a))
}

Laws:

  1. Given a: A then a.patch(Diff.Identical) == Right(a)
  2. Given a1: A and a2: A we should have a1.patch(a1.diff(a2)) == Right(a2)
  3. Given a1: A and a2: A we should have
val diff1 = a1.diff(a2)
val diff2 = a2.diff(a1)
a1.patch(diff1).flatMap(_.diff(diff2)) == Right(a1)

Some questions:

  1. Should the patching be able to fail if the the structure is correct. That is, should the signature be def patch(diff: Diff): Either[String, A => A] instead?
@thinkharderdev thinkharderdev added feature New library features good first issue Good for newcomers labels Sep 7, 2021
@dmitrykozinets
Copy link
Contributor

I would like to give this one a try.

The 2 proposed signatures are:
def patch(diff: Diff): Either[String, A => Either[String,A]]
and
def patch(diff: Diff): Either[String, A => A]

If we have a type A when can the function fail going from A to A?

Not sure how to deal with String... For example:
val diff1 = "abc" diffEach "xyaz"
which produces: Myers(Chunk(Insert(x),Insert(y),Keep(a),Insert(z),Delete(b),Delete(c)))

How do you apply diff1 to some other random String like "hello"?
Or should this fail when one of the steps (Insert, Keep or Delete) do not match and are not doable?

Any other thoughts or guidance would be appreciated as I am new to the Zio community.

@thinkharderdev
Copy link
Contributor Author

Thanks!

The way I was thinking about it is that the patch is intended to be applied to the original value so applying to completely different value creates a "merge conflict" which would fail.

In general, I think the main guideline for this one is that the patch itself should be pure data so we want to make it operation based and serializable. The string diff is already operation based but other diffs are not explicitly encoded that way currently. As an example, check out how we encode (and then apply) migrations in zio.schema.ast.Migration.

dmitrykozinets added a commit to dmitrykozinets/zio-schema that referenced this issue Oct 19, 2021
dmitrykozinets added a commit to dmitrykozinets/zio-schema that referenced this issue Oct 19, 2021
dmitrykozinets added a commit to dmitrykozinets/zio-schema that referenced this issue Oct 19, 2021
thinkharderdev pushed a commit that referenced this issue Oct 29, 2021
* Patch value with Diff #81

* Patch value with Diff #81

* Patch value with Diff #81

* Patch value with a Diff - fixing tests

* Patch value with a Diff - fix formatting

* Patch Value with a Diff - fixing formatting

* Patch value with a Diff - fixing lint errors

* Patch Value with a Diff - Fixing the Either case

* Patch value for a Diff - fixed the either cases

* Patch Value with a Diff - Added more tests

* Patch Value with a Diff - fixing temporal fields

* Patch Value with a Diff - move patch to Diff

* Patch value with a Diff - removing patch from Differ
@thinkharderdev
Copy link
Contributor Author

Closed by #132

landlockedsurfer pushed a commit to landlockedsurfer/zio-schema that referenced this issue May 28, 2022
* Patch value with Diff zio#81

* Patch value with Diff zio#81

* Patch value with Diff zio#81

* Patch value with a Diff - fixing tests

* Patch value with a Diff - fix formatting

* Patch Value with a Diff - fixing formatting

* Patch value with a Diff - fixing lint errors

* Patch Value with a Diff - Fixing the Either case

* Patch value for a Diff - fixed the either cases

* Patch Value with a Diff - Added more tests

* Patch Value with a Diff - fixing temporal fields

* Patch Value with a Diff - move patch to Diff

* Patch value with a Diff - removing patch from Differ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New library features good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants