Skip to content

Commit 74fcdd4

Browse files
committed
Adding indices to slices and supporting json output in report
1 parent f6b7278 commit 74fcdd4

File tree

4 files changed

+59
-36
lines changed

4 files changed

+59
-36
lines changed

config.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ type config struct {
2626
}
2727

2828
type output struct {
29-
Indent string `long:"indent" description:"indent string" default:"\t"`
30-
ShowTypes bool `long:"show-types" short:"t" description:"show types"`
31-
Colorized bool
32-
JSON bool `long:"json" description:"json-style output"`
29+
Indent string `long:"indent" description:"indent string" default:"\t"`
30+
ShowTypes bool `long:"show-types" short:"t" description:"show types"`
31+
Colorized bool
32+
JSON bool `long:"json" description:"json-style output"`
33+
JSONValues bool
3334
}
3435

3536
func readConfig() config {
@@ -52,9 +53,11 @@ func readConfig() config {
5253
fmt.Fprintf(os.Stderr, "Incompatible options --json and --show-types\n")
5354
os.Exit(statusUsage)
5455
}
56+
if c.JSON {
57+
c.JSONValues = true
58+
}
5559
if c.JSON && c.OutputReport {
56-
fmt.Fprintf(os.Stderr, "Incompatible options --json and --report\n")
57-
os.Exit(statusUsage)
60+
c.JSON = false
5861
}
5962

6063
c.output.Colorized = terminal.IsTerminal(int(os.Stdout.Fd()))

diff/output.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@ import (
99

1010
// Output is used to configure the output of the Strings and StringIndent functions.
1111
type Output struct {
12-
Indent string
13-
ShowTypes bool
14-
Colorized bool
15-
JSON bool
12+
Indent string
13+
ShowTypes bool
14+
Colorized bool
15+
JSON bool
16+
JSONValues bool
1617
}
1718

1819
func (o Output) red(v interface{}) string {
1920
var s string
2021

2122
if o.ShowTypes {
2223
s = fmt.Sprintf("%T %v", v, v)
23-
} else if o.JSON {
24+
} else if o.JSONValues {
2425
s = jsonString(v)
2526
} else {
2627
s = fmt.Sprintf("%v", v)
@@ -38,7 +39,7 @@ func (o Output) green(v interface{}) string {
3839

3940
if o.ShowTypes {
4041
s = fmt.Sprintf("%T %v", v, v)
41-
} else if o.JSON {
42+
} else if o.JSONValues {
4243
s = jsonString(v)
4344
} else {
4445
s = fmt.Sprintf("%v", v)
@@ -56,7 +57,7 @@ func (o Output) white(v interface{}) string {
5657

5758
if o.ShowTypes {
5859
s = fmt.Sprintf("%T %v", v, v)
59-
} else if o.JSON {
60+
} else if o.JSONValues {
6061
s = jsonString(v)
6162
} else {
6263
s = fmt.Sprintf("%v", v)

diff/output_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ func TestOutput(t *testing.T) {
4444
},
4545
{
4646
Output: Output{
47-
Indent: "\t",
48-
Colorized: true,
49-
ShowTypes: false,
50-
JSON: true,
47+
Indent: "\t",
48+
Colorized: true,
49+
ShowTypes: false,
50+
JSON: true,
51+
JSONValues: true,
5152
},
5253
WantVal: []string{"5"},
5354
WantType: []string{},

diff/slice.go

+37-19
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ package diff
33
import (
44
"fmt"
55
"reflect"
6+
"strconv"
67
"strings"
78

89
myersdiff "github.com/mb0/diff"
910
)
1011

1112
type slice struct {
12-
diffs []Differ
13-
lhs interface{}
14-
rhs interface{}
13+
diffs []Differ
14+
indices []int
15+
lhs interface{}
16+
rhs interface{}
1517
}
1618

1719
type sliceMissing struct {
@@ -40,39 +42,45 @@ func (d *diffData) Equal(i, j int) bool {
4042
return diff.Diff() == Identical
4143
}
4244

43-
func myersToDiff(conf config, lhs, rhs reflect.Value, changes []myersdiff.Change) []Differ {
45+
func myersToDiff(conf config, lhs, rhs reflect.Value, changes []myersdiff.Change) ([]Differ, []int) {
4446
res := []Differ{}
47+
indices := []int{}
4548

4649
lhsIdx := 0
4750
rhsIdx := 0
4851
for _, c := range changes {
4952
for i := 0; lhsIdx+i < c.A; i++ {
5053
diff, _ := diff(conf, lhs.Index(lhsIdx+i).Interface(), rhs.Index(rhsIdx+i).Interface(), &visited{})
5154
res = append(res, diff)
55+
indices = append(indices, lhsIdx+i)
5256
}
5357
lhsIdx = c.A
5458
rhsIdx = c.B
5559
for d := 0; d < c.Del; d++ {
5660
res = append(res, sliceMissing{lhs.Index(lhsIdx + d).Interface()})
61+
indices = append(indices, lhsIdx+d)
5762
}
5863
lhsIdx += c.Del
5964
for i := 0; i < c.Ins; i++ {
6065
res = append(res, sliceExcess{rhs.Index(rhsIdx + i).Interface()})
66+
indices = append(indices, rhsIdx+i)
6167
}
6268
rhsIdx += c.Ins
6369
}
6470

6571
for lhsIdx < lhs.Len() && rhsIdx < rhs.Len() {
6672
diff, _ := diff(conf, lhs.Index(lhsIdx).Interface(), rhs.Index(rhsIdx).Interface(), &visited{})
6773
res = append(res, diff)
74+
indices = append(indices, lhsIdx)
6875
lhsIdx++
6976
rhsIdx++
7077
}
71-
return res
78+
return res, indices
7279
}
7380

7481
func newMyersSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error) {
7582
var diffs []Differ
83+
var indices []int
7684

7785
lhsVal := reflect.ValueOf(lhs)
7886
rhsVal := reflect.ValueOf(rhs)
@@ -91,25 +99,28 @@ func newMyersSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, er
9199
}
92100
myers := myersdiff.Diff(lhsVal.Len(), rhsVal.Len(), &dData)
93101

94-
diffs = myersToDiff(c, lhsVal, rhsVal, myers)
102+
diffs, indices = myersToDiff(c, lhsVal, rhsVal, myers)
95103
if dData.lastError != nil {
96104
return slice{
97-
lhs: lhs,
98-
rhs: rhs,
99-
diffs: diffs,
105+
lhs: lhs,
106+
rhs: rhs,
107+
diffs: diffs,
108+
indices: indices,
100109
}, dData.lastError
101110
}
102111
}
103112

104113
return slice{
105-
lhs: lhs,
106-
rhs: rhs,
107-
diffs: diffs,
114+
lhs: lhs,
115+
rhs: rhs,
116+
diffs: diffs,
117+
indices: indices,
108118
}, nil
109119
}
110120

111121
func newSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error) {
112122
var diffs []Differ
123+
var indices []int
113124

114125
lhsVal := reflect.ValueOf(lhs)
115126
rhsVal := reflect.ValueOf(rhs)
@@ -126,15 +137,17 @@ func newSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error)
126137
}
127138

128139
for i := 0; i < nElems; i++ {
140+
indices = append(indices, i)
129141
if i < lhsVal.Len() && i < rhsVal.Len() {
130142
diff, err := diff(c, lhsVal.Index(i).Interface(), rhsVal.Index(i).Interface(), visited)
131143
diffs = append(diffs, diff)
132144

133145
if err != nil {
134146
return slice{
135-
lhs: lhs,
136-
rhs: rhs,
137-
diffs: diffs,
147+
lhs: lhs,
148+
rhs: rhs,
149+
diffs: diffs,
150+
indices: indices,
138151
}, err
139152
}
140153
continue
@@ -148,9 +161,10 @@ func newSlice(c config, lhs, rhs interface{}, visited *visited) (Differ, error)
148161
}
149162

150163
return slice{
151-
lhs: lhs,
152-
rhs: rhs,
153-
diffs: diffs,
164+
lhs: lhs,
165+
rhs: rhs,
166+
diffs: diffs,
167+
indices: indices,
154168
}, nil
155169
}
156170

@@ -247,7 +261,7 @@ func (s slice) openString(key, prefix string, conf Output) string {
247261

248262
func (s slice) Walk(path string, fn WalkFn) error {
249263
for i, diff := range s.diffs {
250-
d, err := walk(s, diff, path+"[]", fn)
264+
d, err := walk(s, diff, path+"["+strconv.Itoa(s.lhsIndex(i))+"]", fn)
251265
if err != nil {
252266
return err
253267
}
@@ -259,6 +273,10 @@ func (s slice) Walk(path string, fn WalkFn) error {
259273
return nil
260274
}
261275

276+
func (s slice) lhsIndex(i int) int {
277+
return s.indices[i]
278+
}
279+
262280
func (s slice) LHS() interface{} {
263281
return s.lhs
264282
}

0 commit comments

Comments
 (0)