Documentation ¶
Overview ¶
Package diff provides utilities to generate deep, walkable diffs of maps and slices
Index ¶
- Variables
- func IsExcess(d Differ) bool
- func IsIgnore(d Differ) bool
- func IsMap(d Differ) bool
- func IsMissing(d Differ) bool
- func IsScalar(d Differ) bool
- func IsSlice(d Differ) bool
- func IsStream(d Differ) bool
- func IsTypes(d Differ) bool
- func LHS(d Differ) (interface{}, error)
- func RHS(d Differ) (interface{}, error)
- func Report(d Differ, outConf Output) ([]string, error)
- type ConfigOpt
- type Differ
- type ErrLHSNotSupported
- type ErrRHSNotSupported
- type ErrUnsupported
- type JSONStream
- type Output
- type Stream
- type Type
- type WalkFn
- type Walker
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrCyclic = errors.New("circular references not supported")
ErrCyclic is returned when one of the compared values contain circular references
Functions ¶
func IsExcess ¶
IsExcess returns true if d represent value missing from the LHS (in a map or an array)
func IsMissing ¶
IsMissing returns true if d represent value missing from the RHS (in a map or an array)
func IsScalar ¶ added in v0.1.2
IsScalar returns true of d is a diff between two values that can be compared (int, float64, string, ...)
func IsTypes ¶ added in v0.1.2
IsTypes returns true if d is a diff between two values of different types that cannot be compared
func Report ¶
Report generates a flat list of differences encountered in the diff tree. Its output is less verbose than StringIndent as it doesn't report on matching values.
Example ¶
package main import ( "fmt" "github.com/yazgazan/jaydiff/diff" ) func main() { lhs := map[string]interface{}{ "a": 42, "b": []int{1, 2}, "c": "abc", } rhs := map[string]interface{}{ "a": 21, "b": []int{1, 2, 3}, "c": "abc", } d, _ := diff.Diff(lhs, rhs) reports, _ := diff.Report(d, diff.Output{ Indent: " ", ShowTypes: true, }) for _, report := range reports { fmt.Println(report) } }
Output: - .a: int 42 + .a: int 21 + .b[2]: int 3
Types ¶
type ConfigOpt ¶ added in v0.1.3
type ConfigOpt func(config) config
ConfigOpt is used to pass configuration options to the diff algorithm
func UseSliceMyers ¶ added in v0.1.3
func UseSliceMyers() ConfigOpt
UseSliceMyers configures the Diff function to use Myers' algorithm for slices
type Differ ¶
type Differ interface { Diff() Type Strings() []string StringIndent(key, prefix string, conf Output) string }
Differ is implemented by all nodes in a diff-tree.
func Diff ¶
Diff generates a tree representing differences and similarities between two objects.
Diff supports maps, slices, Stream and scalars (comparables types such as int, string, etc ...). When an unsupported type is encountered, an ErrUnsupported error is returned.
Example ¶
package main import ( "fmt" "github.com/yazgazan/jaydiff/diff" ) func main() { lhs := map[string]interface{}{ "a": 42, "b": []int{1, 2}, "c": "abc", } rhs := map[string]interface{}{ "a": 21, "b": []int{1, 2, 3}, "c": "abc", } d, _ := diff.Diff(lhs, rhs) fmt.Println(d.StringIndent("", "", diff.Output{ Indent: " ", ShowTypes: true, })) }
Output: map[string]interface {} map[ - a: int 42 + a: int 21 b: []int [ int 1 int 2 + int 3 ] c: string abc ]
Example (Struct) ¶
package main import ( "fmt" "github.com/yazgazan/jaydiff/diff" ) func main() { type subStruct struct { Hello int World float64 } type structA struct { Foo int Bar string Baz subStruct Ban [2]int priv int } type structB struct { Foo int Bar string Baz subStruct Ban [2]int priv int } lhs := structA{ Foo: 42, Bar: "hello", Baz: subStruct{ Hello: 11, World: 3.5, }, Ban: [2]int{3, 5}, priv: 0, } rhs := structB{ Foo: 21, Bar: "hello", Baz: subStruct{ Hello: 11, World: 3.5, }, Ban: [2]int{3, 7}, priv: 1, } d, err := diff.Diff(lhs, rhs) if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println(d.StringIndent("", "", diff.Output{ Indent: " ", ShowTypes: true, })) }
Output: diff_test.structA map[ Ban: [2]int [ int 3 - int 5 + int 7 ] Bar: string hello Baz: diff_test.subStruct {11 3.5} - Foo: int 42 + Foo: int 21 ]
func Walk ¶
Walk allows to descend a diff tree and replace/edit its leaves and branches. When fn returns a non-nil Differ, the current node is replaced and the new node is walked over (if walkable).
Example ¶
package main import ( "fmt" "strings" "github.com/yazgazan/jaydiff/diff" ) func main() { lhs := map[string]interface{}{ "a": 42, "b": []int{1, 2}, "will_be_ignored": []int{3, 4}, "c": "abc", } rhs := map[string]interface{}{ "a": 41, "b": []int{1, 2}, "will_be_ignored": 5, "c": "abc", "exess_key": "will be ignored", } d, _ := diff.Diff(lhs, rhs) fmt.Println("Before:") fmt.Println(d.StringIndent("", "", diff.Output{ Indent: " ", ShowTypes: true, })) d, _ = diff.Walk(d, func(parent diff.Differ, d diff.Differ, path string) (diff.Differ, error) { if strings.HasSuffix(path, ".will_be_ignored") || diff.IsExcess(d) { return diff.Ignore() } return nil, nil }) fmt.Println("After:") fmt.Println(d.StringIndent("", "", diff.Output{ Indent: " ", ShowTypes: true, })) }
Output: Before: map[string]interface {} map[ - a: int 42 + a: int 41 b: []int [1 2] c: string abc + exess_key: string will be ignored - will_be_ignored: []int [3 4] + will_be_ignored: int 5 ] After: map[string]interface {} map[ - a: int 42 + a: int 41 b: []int [1 2] c: string abc ]
type ErrLHSNotSupported ¶ added in v0.1.4
type ErrLHSNotSupported struct {
Diff Differ
}
ErrLHSNotSupported is returned when calling diff.LHS on a Differ that does not contain an LHS value (i.e Ignore)
func (ErrLHSNotSupported) Error ¶ added in v0.1.4
func (e ErrLHSNotSupported) Error() string
type ErrRHSNotSupported ¶ added in v0.1.4
type ErrRHSNotSupported struct {
Diff Differ
}
ErrRHSNotSupported is returned when calling diff.EHS on a Differ that does not contain an RHS value (i.e Ignore)
func (ErrRHSNotSupported) Error ¶ added in v0.1.4
func (e ErrRHSNotSupported) Error() string
type ErrUnsupported ¶
ErrUnsupported is returned when an unsupported type is encountered (func, struct ...).
func (ErrUnsupported) Error ¶
func (e ErrUnsupported) Error() string
type JSONStream ¶ added in v0.3.0
func (*JSONStream) NextValue ¶ added in v0.3.0
func (s *JSONStream) NextValue() (interface{}, error)
type Type ¶
type Type int
Type is used to specify the nature of the difference
const ( // TypesDiffer is used when two values cannot be compared due to types differences // (for example: comparing a slice to an int) TypesDiffer Type = iota // ContentDiffer is used when the types matches but the content differs ContentDiffer // Identical is used when both the type and the content match. Identical // Invalid is used when calling Diff() on an inproperly constructed node Invalid )