gnieh / diffson

A scala diff/patch library for Json
Apache License 2.0
315 stars 51 forks source link

Issues with indexes list #426

Closed salvaromanes closed 4 months ago

salvaromanes commented 5 months ago

Hello guys,

I have found one issue with a case in which two Json contain indexed lists inside their bodies. I'm trying to show the differences between two indexed lists but when the differences Json is returning I don't get the correct solution for the changes. I'm going to show one example with the solution that I expect and the one that I get.

Example:

entryJson1 =
    """{
      |  "name": "John",
      |  "surname": "Smith",
      |  "transport" : [{
      |    "street" : [{
      |      "cars": [
      |        { "audi": "a1" },
      |        { "renault": "clio" },
      |        { "ford": "focus" },
      |        { "audi": "a5" }
      |      ]
      |    }]
      |  }]
      |}"""

  entryJson2 =
    """{
      |  "name": "Jack",
      |  "surname": "Smith",
      |  "transport" : [{
      |    "street" : [{
      |      "cars": [
      |        { "audi": "a1" },
      |        { "ford": "focus" }
      |      ]
      |    }]
      |  }],
      |  "nationality" : "german"
      |}"""

Solution I get:

{
  "change" : [
    {
      "path" : "name",
      "new" : "Jack",
      "old" : "John"
    }
  ],
  "remove" : [
    {
      "path" : "transport.0.street.0.cars.1",
      "old" : {
        "renault" : "clio"
      }
    },
    {
      "path" : "transport.0.street.0.cars.2",
      "old" : {
        "audi" : "a5"
      }
    }
  ],
  "add" : [
    {
      "path" : "nationality",
      "new" : "german"
    }
  ]
}

Solution I expect:

{
  "change" : [
    {
      "path" : "name",
      "new" : "Jack",
      "old" : "John"
    }
  ],
  "remove" : [
    {
      "path" : "transport.0.street.0.cars.1",
      "old" : {
        "renault" : "clio"
      }
    },
    {
      **"path" : "transport.0.street.0.cars.3", <- this is the wrong data**
      "old" : {
        "audi" : "a5"
      }
    }
  ],
  "add" : [
    {
      "path" : "nationality",
      "new" : "german"
    }
  ]
}

Someone knows what is happening? I'm using circe and diffson with remembering.

satabin commented 4 months ago

Hi and thanks for reporting.

This is actually ok, since you need to remember that the update operations are applied sequentially. So, once element at index 1 has been deleted, you need to shift indices by one. So element originally at index 3 becomes element at index 2.

The relevant portion of the RFC is:

Operations are applied sequentially in the order they appear in the array. Each operation in the sequence is applied to the target document; the resulting document becomes the target of the next operation.

satabin commented 4 months ago

Also looking at your output, this is not a JSON Patch format, did you transform what diffson output? What format is this?

satabin commented 4 months ago

Given the initial concern raised, I consider this question answered and am closing the issue. If you think the problem persists, please feel free to reopen this issue and comment with your concern.