Skip to content

Commit 41cc38a

Browse files
committed
write: use bufio instead of errWriter
This simplifies the code and improves performance. The downside is that we no longer know the number of bytes written. (This entails an API change, which is the reason to do it now, while we can.) But this is not a common need, and worst case, callers can count themselves by wrapping their writer in a counting writer.
1 parent 4849219 commit 41cc38a

File tree

5 files changed

+27
-73
lines changed

5 files changed

+27
-73
lines changed

diff.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func Text(aFile, bFile string, a, b interface{}, w io.Writer, options ...write.O
8484
s := myers.Diff(context.Background(), ab)
8585
s = ctxt.Size(s, 3)
8686
opts := addNames(aFile, bFile, options)
87-
_, err = write.Unified(s, w, ab, opts...)
87+
err = write.Unified(s, w, ab, opts...)
8888
return err
8989
}
9090

@@ -110,7 +110,7 @@ func Slices(aName, bName string, a, b interface{}, w io.Writer, options ...write
110110
s := myers.Diff(context.Background(), ab)
111111
s = ctxt.Size(s, 3)
112112
opts := addNames(aName, bName, options)
113-
_, err := write.Unified(s, w, ab, opts...)
113+
err := write.Unified(s, w, ab, opts...)
114114
return err
115115
}
116116

fuzz.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func Fuzz(data []byte) int {
2929
ab := &IndividualBytes{a: a, b: b}
3030
s := myers.Diff(context.Background(), ab)
3131
s = ctxt.Size(s, sz)
32-
_, err := write.Unified(s, ioutil.Discard, ab)
32+
err := write.Unified(s, ioutil.Discard, ab)
3333
if err != nil {
3434
panic(err)
3535
}

write/errwriter.go

Lines changed: 0 additions & 45 deletions
This file was deleted.

write/unified.go

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package write
22

33
import (
4+
"bufio"
45
"fmt"
56
"io"
67

@@ -21,7 +22,7 @@ type Pair interface {
2122
// Unified returns the number of bytes written and the first error (if any) encountered.
2223
// Before writing, edit scripts usually have their context reduced,
2324
// such as by a call to ctxt.Size.
24-
func Unified(e edit.Script, w io.Writer, ab Pair, opts ...Option) (int, error) {
25+
func Unified(e edit.Script, w io.Writer, ab Pair, opts ...Option) error {
2526
// read opts
2627
nameA := "a"
2728
nameB := "b"
@@ -39,19 +40,17 @@ func Unified(e edit.Script, w io.Writer, ab Pair, opts ...Option) (int, error) {
3940
}
4041
}
4142

42-
ew := newErrWriter(w)
43-
// TODO: Wrap w in a bufio.Writer? And then use w.WriteByte below instead of w.Write.
44-
// Maybe bufio.Writer is enough and we should entirely ditch newErrWriter.
43+
bw := bufio.NewWriter(w)
4544

4645
needsColorReset := false
4746

4847
// per-file header
4948
if color {
50-
ew.WriteString(ansiBold)
49+
bw.WriteString(ansiBold)
5150
needsColorReset = true
5251
}
53-
fmt.Fprintf(ew, "--- %s\n", nameA)
54-
fmt.Fprintf(ew, "+++ %s\n", nameB)
52+
fmt.Fprintf(bw, "--- %s\n", nameA)
53+
fmt.Fprintf(bw, "+++ %s\n", nameB)
5554

5655
for i := 0; i < len(e.Ranges); {
5756
// Peek into the future to learn the line ranges for this chunk of output.
@@ -92,48 +91,48 @@ func Unified(e edit.Script, w io.Writer, ab Pair, opts ...Option) (int, error) {
9291
// and we can have EditScript methods to populate it somehow?
9392
if color {
9493
if needsColorReset {
95-
ew.WriteString(ansiReset)
94+
bw.WriteString(ansiReset)
9695
}
97-
ew.WriteString(ansiFgBlue)
96+
bw.WriteString(ansiFgBlue)
9897
needsColorReset = true
9998
}
100-
fmt.Fprintf(ew, "@@ -%s +%s @@\n", ar, br)
99+
fmt.Fprintf(bw, "@@ -%s +%s @@\n", ar, br)
101100

102101
// Print prefixed lines.
103102
for k := i; k <= j; k++ {
104103
seg := e.Ranges[k]
105104
switch seg.Op() {
106105
case edit.Eq:
107106
if needsColorReset {
108-
ew.WriteString(ansiReset)
107+
bw.WriteString(ansiReset)
109108
}
110109
for m := seg.LowA; m < seg.HighA; m++ {
111110
// " a[m]\n"
112-
ew.WriteByte(' ')
113-
ab.WriteATo(ew, m)
114-
ew.WriteByte('\n')
111+
bw.WriteByte(' ')
112+
ab.WriteATo(bw, m)
113+
bw.WriteByte('\n')
115114
}
116115
case edit.Del:
117116
if color {
118-
ew.WriteString(ansiFgRed)
117+
bw.WriteString(ansiFgRed)
119118
needsColorReset = true
120119
}
121120
for m := seg.LowA; m < seg.HighA; m++ {
122121
// "-a[m]\n"
123-
ew.WriteByte('-')
124-
ab.WriteATo(ew, m)
125-
ew.WriteByte('\n')
122+
bw.WriteByte('-')
123+
ab.WriteATo(bw, m)
124+
bw.WriteByte('\n')
126125
}
127126
case edit.Ins:
128127
if color {
129-
ew.WriteString(ansiFgGreen)
128+
bw.WriteString(ansiFgGreen)
130129
needsColorReset = true
131130
}
132131
for m := seg.LowB; m < seg.HighB; m++ {
133132
// "+b[m]\n"
134-
ew.WriteByte('+')
135-
ab.WriteBTo(ew, m)
136-
ew.WriteByte('\n')
133+
bw.WriteByte('+')
134+
ab.WriteBTo(bw, m)
135+
bw.WriteByte('\n')
137136
}
138137
}
139138
}
@@ -147,7 +146,7 @@ func Unified(e edit.Script, w io.Writer, ab Pair, opts ...Option) (int, error) {
147146
// Always finish the output with no color, to prevent "leaking" the
148147
// color into any output that follows a diff.
149148
if needsColorReset {
150-
ew.WriteString(ansiReset)
149+
bw.WriteString(ansiReset)
151150
}
152151

153152
// TODO:
@@ -156,7 +155,7 @@ func Unified(e edit.Script, w io.Writer, ab Pair, opts ...Option) (int, error) {
156155
// and the following line in the chunk has the literal text (starting in the first column):
157156
// '\ No newline at end of file'
158157

159-
return ew.wrote, ew.Error()
158+
return bw.Flush()
160159
}
161160

162161
type lineRange struct {

write/unified_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func TestGolden(t *testing.T) {
8686
e := myers.Diff(context.Background(), ab)
8787
e = ctxt.Size(e, 3)
8888
buf := new(bytes.Buffer)
89-
_, err := write.Unified(e, buf, ab, test.opts...)
89+
err := write.Unified(e, buf, ab, test.opts...)
9090
if err != nil {
9191
t.Fatal(err)
9292
}

0 commit comments

Comments
 (0)