Skip to content

Commit

Permalink
Use internal/json
Browse files Browse the repository at this point in the history
  • Loading branch information
evanphx committed Jan 12, 2024
1 parent f18a498 commit 7b8895c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 40 deletions.
14 changes: 9 additions & 5 deletions v5/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package jsonpatch

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"reflect"

"github.com/evanphx/json-patch/v5/internal/json"
)

func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode {
Expand Down Expand Up @@ -123,7 +124,9 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {

docErr := unmarshal(docData, doc)

patch := &partialDoc{}
patch := &partialDoc{
fastKeys: true,
}

patchErr := unmarshal(patchData, patch)

Expand All @@ -144,6 +147,9 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
}

if patchErr == nil && patch.obj == nil {
if json.Valid(patchData) {
return patchData, nil
}
return nil, errBadJSONPatch
}

Expand Down Expand Up @@ -262,9 +268,7 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
}

func unmarshal(data []byte, into interface{}) error {
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
return dec.Decode(into)
return json.Unmarshal(data, into)
}

// createArrayMergePatch will return an array of merge-patch documents capable
Expand Down
21 changes: 11 additions & 10 deletions v5/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"testing"
)

func mergePatch(doc, patch string) string {
func mergePatch(t *testing.T, doc, patch string) string {
t.Helper()
out, err := MergePatch([]byte(doc), []byte(patch))

if err != nil {
panic(fmt.Sprintf("%s: %s", err, patch))
t.Errorf(fmt.Sprintf("%s: %s", err, patch))
}

return string(out)
Expand All @@ -19,7 +20,7 @@ func TestMergePatchReplaceKey(t *testing.T) {
doc := `{ "title": "hello" }`
pat := `{ "title": "goodbye" }`

res := mergePatch(doc, pat)
res := mergePatch(t, doc, pat)

if !compareJSON(pat, res) {
t.Fatalf("Key was not replaced")
Expand All @@ -30,7 +31,7 @@ func TestMergePatchIgnoresOtherValues(t *testing.T) {
doc := `{ "title": "hello", "age": 18 }`
pat := `{ "title": "goodbye" }`

res := mergePatch(doc, pat)
res := mergePatch(t, doc, pat)

exp := `{ "title": "goodbye", "age": 18 }`

Expand All @@ -43,7 +44,7 @@ func TestMergePatchNilDoc(t *testing.T) {
doc := `{ "title": null }`
pat := `{ "title": {"foo": "bar"} }`

res := mergePatch(doc, pat)
res := mergePatch(t, doc, pat)

exp := `{ "title": {"foo": "bar"} }`

Expand All @@ -70,7 +71,7 @@ func TestMergePatchNilArray(t *testing.T) {

for _, c := range cases {
t.Log(c.original)
act := mergePatch(c.original, c.patch)
act := mergePatch(t, c.original, c.patch)

if !compareJSON(c.res, act) {
t.Errorf("null values not preserved in array")
Expand All @@ -82,7 +83,7 @@ func TestMergePatchRecursesIntoObjects(t *testing.T) {
doc := `{ "person": { "title": "hello", "age": 18 } }`
pat := `{ "person": { "title": "goodbye" } }`

res := mergePatch(doc, pat)
res := mergePatch(t, doc, pat)

exp := `{ "person": { "title": "goodbye", "age": 18 } }`

Expand Down Expand Up @@ -111,7 +112,7 @@ func TestMergePatchReplacesNonObjectsWholesale(t *testing.T) {
}

for _, c := range cases {
act := mergePatch(c.doc, c.pat)
act := mergePatch(t, c.doc, c.pat)

if !compareJSON(c.res, act) {
t.Errorf("whole object replacement failed")
Expand Down Expand Up @@ -175,7 +176,7 @@ var rfcTests = []struct {

func TestMergePatchRFCCases(t *testing.T) {
for i, c := range rfcTests {
out := mergePatch(c.target, c.patch)
out := mergePatch(t, c.target, c.patch)

if !compareJSON(out, c.expected) {
t.Errorf("case[%d], patch '%s' did not apply properly to '%s'. expected:\n'%s'\ngot:\n'%s'", i, c.patch, c.target, c.expected, out)
Expand Down Expand Up @@ -621,7 +622,7 @@ func TestMergePatchReplaceKeyNotEscaping(t *testing.T) {
pat := `{ "obj": { "title/escaped": "goodbye" } }`
exp := `{ "obj": { "title/escaped": "goodbye" } }`

res := mergePatch(doc, pat)
res := mergePatch(t, doc, pat)

if !compareJSON(exp, res) {
t.Fatalf("Key was not replaced")
Expand Down
35 changes: 10 additions & 25 deletions v5/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package jsonpatch

import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"

"github.com/evanphx/json-patch/v5/internal/json"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -59,6 +59,8 @@ type partialDoc struct {
self *lazyNode
keys []string
obj map[string]*lazyNode

fastKeys bool
}

type partialArray struct {
Expand Down Expand Up @@ -133,7 +135,7 @@ func (n *lazyNode) UnmarshalJSON(data []byte) error {
}

func (n *partialDoc) MarshalJSON() ([]byte, error) {
var buf bytes.Buffer
var buf strings.Builder
if _, err := buf.WriteString("{"); err != nil {
return nil, err
}
Expand Down Expand Up @@ -164,7 +166,7 @@ func (n *partialDoc) MarshalJSON() ([]byte, error) {
if _, err := buf.WriteString("}"); err != nil {
return nil, err
}
return buf.Bytes(), nil
return []byte(buf.String()), nil
}

type syntaxError struct {
Expand All @@ -176,30 +178,13 @@ func (err *syntaxError) Error() string {
}

func (n *partialDoc) UnmarshalJSON(data []byte) error {
if err := unmarshal(data, &n.obj); err != nil {
return err
}
buffer := bytes.NewBuffer(data)
d := json.NewDecoder(buffer)
if t, err := d.Token(); err != nil {
keys, err := json.UnmarshalWithKeys(data, &n.obj)
if err != nil {
return err
} else if t != startObject {
return &syntaxError{fmt.Sprintf("unexpected JSON token in document node: %v", t)}
}
for d.More() {
k, err := d.Token()
if err != nil {
return err
}
key, ok := k.(string)
if !ok {
return &syntaxError{fmt.Sprintf("unexpected JSON token as document node key: %s", k)}
}
if err := skipValue(d); err != nil {
return err
}
n.keys = append(n.keys, key)
}

n.keys = keys

return nil
}

Expand Down

0 comments on commit 7b8895c

Please sign in to comment.