patchstructure is a Go library for applying patches to modify existing Go structures.
patchstructure is based on JSON Patch (RFC 6902), but applies to Go strucutures instead of JSON objects.
The goal of patchstructure is to provide a single API and format for representing and applying changes to Go structures. With this in place, diffs between structures can be represented, changes to a structure can be treated as a log, etc.
-
Apply a "patch" to perform a set of operations on a Go structure
-
Operations support add, remove, replace, move, copy
-
Operations work on all Go primitive types and collection types
-
JSON encode/decode Operation structures
For an exhaustive list of supported features, please view the JSON Patch RFC (RFC 6902) which this implements completely, but for Go structures. Exceptions to the RFC are documented below.
RFC 6902 was created for JSON structures. Due to minor differences in Go structures, there are some differences. These don't change the function of the RFC, but are important to know when using this library:
-
The "copy" operation will perform a deep copy by default using copystructure. You can set the
Shallow
field to true on the operation to avoid this behavior. -
The "test" operation is currently implemented with
reflect.DeepEqual
which is not exactly correct according to the RFC. This will work fine for most basic primitives but the limitations of that approach should be known. In the future we should rework this.
Standard go get
:
$ go get github.com/mitchellh/patchstructure
For usage and examples see the Godoc.
A quick code example is shown below:
complex := map[string]interface{}{
"alice": 42,
"bob": []interface{}{
map[string]interface{}{
"name": "Bob",
},
},
}
value, err := Patch(complex, []*Operation{
&Operation{
Op: OpCopy,
Path: "/alice",
From: "/bob",
},
&Operation{
Op: OpReplace,
Path: "/alice/0/name",
Value: "Alice",
},
})
if err != nil {
panic(err)
}
fmt.Printf("%s", value)
// Output:
// map[alice:[map[name:Alice]] bob:[map[name:Bob]]]