Skip to content

Commit

Permalink
Port support for deleting by value to v5
Browse files Browse the repository at this point in the history
  • Loading branch information
kszafran committed Nov 8, 2023
1 parent 4e249f2 commit a29393f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
33 changes: 32 additions & 1 deletion v5/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ var (
// allowing negative indices to mean indices starting at the end of an array.
// Default to true.
SupportNegativeIndices bool = true
// SupportDeleteByValue decides whether to support non-standard practice of
// allowing deleting from array by value.
SupportDeleteByValue bool = true
// AccumulatedCopySizeLimit limits the total size increase in bytes caused by
// "copy" operations in a patch.
AccumulatedCopySizeLimit int64 = 0
Expand Down Expand Up @@ -76,6 +79,9 @@ type ApplyOptions struct {
// allowing negative indices to mean indices starting at the end of an array.
// Default to true.
SupportNegativeIndices bool
// SupportDeleteByValue decides whether to support non-standard practice of
// allowing deleting from array by value.
SupportDeleteByValue bool
// AccumulatedCopySizeLimit limits the total size increase in bytes caused by
// "copy" operations in a patch.
AccumulatedCopySizeLimit int64
Expand All @@ -91,6 +97,7 @@ type ApplyOptions struct {
func NewApplyOptions() *ApplyOptions {
return &ApplyOptions{
SupportNegativeIndices: SupportNegativeIndices,
SupportDeleteByValue: SupportDeleteByValue,
AccumulatedCopySizeLimit: AccumulatedCopySizeLimit,
AllowMissingPathOnRemove: false,
EnsurePathExistsOnAdd: false,
Expand Down Expand Up @@ -701,6 +708,19 @@ func (d *partialArray) remove(key string, options *ApplyOptions) error {
return nil
}

func (d *partialArray) removeByValue(key *lazyNode, options *ApplyOptions) error {
for i, v := range *d {
if key.equal(v) {
return d.remove(strconv.Itoa(i), options)
}
}

if options.AllowMissingPathOnRemove {
return nil
}
return errors.Wrapf(ErrMissing, "value not found")
}

func (p Patch) add(doc *container, op Operation, options *ApplyOptions) error {
path, err := op.Path()
if err != nil {
Expand Down Expand Up @@ -872,7 +892,18 @@ func (p Patch) remove(doc *container, op Operation, options *ApplyOptions) error
return errors.Wrapf(ErrMissing, "remove operation does not apply: doc is missing path: \"%s\"", path)
}

err = con.remove(key, options)
if key == "-" && options.SupportDeleteByValue {
value := op.value()
switch v := con.(type) {
case *partialArray:
err = v.removeByValue(value, options)
default:
return errors.Wrapf(ErrMissing, "remove operation does not apply: not an array: \"%s\"", path)
}
} else {
err = con.remove(key, options)
}

if err != nil {
return errors.Wrapf(err, "error in remove for path: '%s'", path)
}
Expand Down
25 changes: 25 additions & 0 deletions v5/patch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,27 @@ var Cases = []Case{
false,
false,
},
{
`{ "foo": [ "bar", "qux", "baz" ] }`,
`[ { "op": "remove", "path": "/foo/-" , "value": "qux" }]`,
`{ "foo": [ "bar", "baz" ] }`,
false,
false,
},
{
`{ "foo": [ "3", "2", "1" ] }`,
`[ { "op": "remove", "path": "/foo/-" , "value": "1" }]`,
`{ "foo": [ "3", "2" ] }`,
false,
false,
},
{
`{ "foo": [ [ "bar", "qux", "baz" ], [ "bar", "baz" ], "1" ] }`,
`[ { "op": "remove", "path": "/foo/-" , "value": [ "bar", "baz" ] }]`,
`{ "foo": [ [ "bar", "qux", "baz" ], "1" ] }`,
false,
false,
},
{
`{ "baz": "qux", "foo": "bar" }`,
`[ { "op": "replace", "path": "/baz", "value": "boo" } ]`,
Expand Down Expand Up @@ -665,6 +686,10 @@ var BadCases = []BadCase{
`[ {"op": "remove", "path": "/foo/-"}]`,
false,
},
{
`{ "foo": []}`,
`[ {"op": "remove", "path": "/foo/-", "value": "asd"}]`,
},
{
`{ "foo": []}`,
`[ {"op": "remove", "path": "/foo/-1"}]`,
Expand Down

0 comments on commit a29393f

Please sign in to comment.