diff --git a/differ.go b/differ.go index 67fff03..33389fb 100644 --- a/differ.go +++ b/differ.go @@ -10,12 +10,12 @@ import ( // A Differ is a JSON Patch generator. // The zero value is an empty generator ready to use. type Differ struct { - patch Patch - hasher hasher + opts options hashmap map[uint64]jsonNode + patch Patch targetBytes []byte - opts options ptr pointer + hasher hasher } type ( @@ -24,18 +24,18 @@ type ( ) type options struct { + ignores map[string]struct{} + marshal marshalFunc + unmarshal unmarshalFunc factorize bool rationalize bool invertible bool equivalent bool - ignores map[string]struct{} - marshal marshalFunc - unmarshal unmarshalFunc } type jsonNode struct { - ptr string val any + ptr string } // Patch returns the list of JSON patch operations diff --git a/differ_test.go b/differ_test.go index d5009b1..cb1850f 100644 --- a/differ_test.go +++ b/differ_test.go @@ -157,6 +157,9 @@ func runTestCase(t *testing.T, tc testcase, pc patchGetter, opts ...Option) { } func Benchmark_sortStrings(b *testing.B) { + if testing.Short() { + b.Skip() + } for _, v := range [][]string{ // 5 { diff --git a/example_test.go b/example_test.go index 6a79032..8da9865 100644 --- a/example_test.go +++ b/example_test.go @@ -83,7 +83,7 @@ func ExampleCompare() { fmt.Printf("%s\n", op) } // Output: - // {"op":"replace","path":"/spec/containers/0/image","value":"nginx:1.19.5-alpine"} + // {"value":"nginx:1.19.5-alpine","op":"replace","path":"/spec/containers/0/image"} // {"op":"remove","path":"/spec/volumes/0/emptyDir/medium"} } @@ -146,8 +146,8 @@ func ExampleCompareJSON() { fmt.Printf("%s\n", op) } // Output: - // {"op":"replace","path":"/age","value":30} - // {"op":"add","path":"/phoneNumbers/-","value":{"number":"209-212-0015","type":"mobile"}} + // {"value":30,"op":"replace","path":"/age"} + // {"value":{"number":"209-212-0015","type":"mobile"},"op":"add","path":"/phoneNumbers/-"} } func ExampleInvertible() { @@ -166,11 +166,11 @@ func ExampleInvertible() { fmt.Printf("%s\n", op) } // Output: - // {"op":"test","path":"/a","value":"1"} - // {"op":"replace","path":"/a","value":"3"} - // {"op":"test","path":"/b","value":"2"} + // {"value":"1","op":"test","path":"/a"} + // {"value":"3","op":"replace","path":"/a"} + // {"value":"2","op":"test","path":"/b"} // {"op":"remove","path":"/b"} - // {"op":"add","path":"/c","value":"4"} + // {"value":"4","op":"add","path":"/c"} } func ExampleFactorize() { @@ -238,8 +238,8 @@ func ExampleMarshalFunc() { fmt.Printf("%s\n", op) } // Output: - // {"op":"replace","path":"/spec/containers/0/name","value":"nginx"} - // {"op":"replace","path":"/spec/volumes/0/name","value":"data"} + // {"value":"nginx","op":"replace","path":"/spec/containers/0/name"} + // {"value":"data","op":"replace","path":"/spec/volumes/0/name"} } func ExampleUnmarshalFunc() { @@ -262,7 +262,7 @@ func ExampleUnmarshalFunc() { fmt.Printf("%s\n", op) } // Output: - // {"op":"replace","path":"/A","value":"baz"} - // {"op":"replace","path":"/B","value":3.14159} - // {"op":"replace","path":"/C","value":true} + // {"value":"baz","op":"replace","path":"/A"} + // {"value":3.14159,"op":"replace","path":"/B"} + // {"value":true,"op":"replace","path":"/C"} } diff --git a/operation.go b/operation.go index a18abdc..eeb61f6 100644 --- a/operation.go +++ b/operation.go @@ -31,11 +31,11 @@ type Patch []Operation // Operation represents a single RFC6902 JSON Patch operation. type Operation struct { + Value interface{} `json:"value,omitempty"` + OldValue interface{} `json:"-"` Type string `json:"op"` From string `json:"from,omitempty"` Path string `json:"path"` - OldValue interface{} `json:"-"` - Value interface{} `json:"value,omitempty"` } // String implements the fmt.Stringer interface. diff --git a/operation_test.go b/operation_test.go index 661f639..2e13e5c 100644 --- a/operation_test.go +++ b/operation_test.go @@ -15,7 +15,7 @@ func TestOperationMarshalJSON(t *testing.T) { Path: "/foo/bar", Value: nil, }, - `{"op":"replace","path":"/foo/bar","value":null}`, + `{"value":null,"op":"replace","path":"/foo/bar"}`, }, { Operation{ @@ -23,7 +23,7 @@ func TestOperationMarshalJSON(t *testing.T) { Path: "/foo/bar", Value: typeNilIface(), }, - `{"op":"replace","path":"/foo/bar","value":null}`, + `{"value":null,"op":"replace","path":"/foo/bar"}`, }, { Operation{ @@ -31,7 +31,7 @@ func TestOperationMarshalJSON(t *testing.T) { Path: "/foo/bar", Value: "foo", }, - `{"op":"replace","path":"/foo/bar","value":"foo"}`, + `{"value":"foo","op":"replace","path":"/foo/bar"}`, }, { // assigned interface @@ -40,7 +40,7 @@ func TestOperationMarshalJSON(t *testing.T) { Path: "", Value: nil, }, - `{"op":"add","path":"","value":null}`, + `{"value":null,"op":"add","path":""}`, }, { // unassigned interface Value @@ -48,7 +48,7 @@ func TestOperationMarshalJSON(t *testing.T) { Type: OperationAdd, Path: "", }, - `{"op":"add","path":"","value":null}`, + `{"value":null,"op":"add","path":""}`, }, { Operation{ @@ -56,7 +56,7 @@ func TestOperationMarshalJSON(t *testing.T) { Path: "", Value: typeNilIface(), }, - `{"op":"add","path":"","value":null}`, + `{"value":null,"op":"add","path":""}`, }, { // Remove operation should NEVER be marshaled with @@ -120,7 +120,7 @@ func TestPatchString(t *testing.T) { } s := patch.String() - const expected = `{"op":"replace","path":"/foo/baz","value":42} + const expected = `{"value":42,"op":"replace","path":"/foo/baz"} {"op":"remove","path":"/xxx"} `