Remove unused LineReader interface

This is no longer used for text application, so revert the parser back
to using StringReader.
This commit is contained in:
Billy Keyes
2020-01-23 21:53:31 -08:00
parent 0b7af3feaa
commit 3d1274d16e
3 changed files with 10 additions and 139 deletions
-74
View File
@@ -1,84 +1,10 @@
package gitdiff
import (
"bufio"
"errors"
"fmt"
"io"
)
// StringReader is the interface that wraps the ReadString method.
//
// ReadString reads until the first occurrence of delim in the input, returning
// a string containing the data up to and including the delimiter. If
// ReadString encounters an error before finding a delimiter, it returns the
// data read before the error and the error itself (often io.EOF). ReadString
// returns err != nil if and only if the returned data does not end in delim.
type StringReader interface {
ReadString(delim byte) (string, error)
}
type readStringReader interface {
io.Reader
StringReader
}
// LineReader is the interface that wraps the ReadLine method.
//
// ReadLine reads the next full line in the input, returing the the data
// including the line ending character(s) and the zero-indexed line number. If
// ReadLine encounters an error before reaching the end of the line, it returns
// the data read before the error, the number of the line, and the error itself
// (often io.EOF). ReadLine returns err != nil if and only if the returned data
// is not a complete line.
//
// If an implementation defines other methods for reading the same input, line
// numbers may be incorrect if calls to ReadLine are mixed with calls to other
// read methods.
type LineReader interface {
ReadLine() (string, int64, error)
}
// NewLineReader returns a LineReader starting at a specific line and using the
// newline character, \n, as a line separator. If r is a StringReader, it is
// used directly. Otherwise, it is wrapped in a way that may read extra data
// from the underlying input.
func NewLineReader(r io.Reader, lineno int64) LineReader {
sr, ok := r.(readStringReader)
if !ok {
sr = bufio.NewReader(r)
}
return &lineReader{r: sr, n: lineno}
}
type lineReader struct {
r readStringReader
n int64
}
func (lr *lineReader) ReadLine() (line string, lineno int64, err error) {
lineno = lr.n
line, err = lr.r.ReadString('\n')
if err == nil {
lr.n++
}
return
}
// unwrapLineReader returns a plain io.Reader that was converted to a
// LineReader by wrapping or casting. It should only be called from functions
// that accept an io.Reader as an argument and then convert it.
func unwrapLineReader(lr LineReader) io.Reader {
switch r := lr.(type) {
case io.Reader:
return r
case *lineReader:
return r.r
default:
panic(fmt.Sprintf("%T does not implement io.Reader and is not a gitdiff wrapper", lr))
}
}
// LineReaderAt is the interface that wraps the ReadLinesAt method.
//
// ReadLinesAt reads len(lines) into lines starting at line offset in the
-57
View File
@@ -1,57 +0,0 @@
package gitdiff
import (
"io"
"strings"
"testing"
)
func TestLineReader(t *testing.T) {
const content = "first line\nsecond line\nthird line\npartial fourth line"
t.Run("readLine", func(t *testing.T) {
r := NewLineReader(strings.NewReader(content), 0)
lines := []struct {
Data string
Err error
}{
{"first line\n", nil},
{"second line\n", nil},
{"third line\n", nil},
{"partial fourth line", io.EOF},
}
for i, line := range lines {
d, n, err := r.ReadLine()
if err != line.Err {
if line.Err == nil {
t.Fatalf("error reading line: %v", err)
} else {
t.Fatalf("expected %v while reading line, but got %v", line.Err, err)
}
}
if d != line.Data {
t.Errorf("incorrect line data: expected %q, actual %q", line.Data, d)
}
if n != int64(i) {
t.Errorf("incorrect line number: expected %d, actual %d", i, n)
}
}
})
t.Run("readLineOffset", func(t *testing.T) {
r := NewLineReader(strings.NewReader(content), 10)
d, n, err := r.ReadLine()
if err != nil {
t.Fatalf("error reading line: %v", err)
}
if d != "first line\n" {
t.Errorf("incorrect line data: expected %q, actual %q", "first line\n", d)
}
if n != 10 {
t.Errorf("incorrect line number: expected %d, actual %d", 10, n)
}
})
}
+10 -8
View File
@@ -4,6 +4,7 @@
package gitdiff
import (
"bufio"
"fmt"
"io"
)
@@ -11,9 +12,6 @@ import (
// Parse parses a patch with changes to one or more files. Any content before
// the first file is returned as the second value. If an error occurs while
// parsing, it returns all files parsed before the error.
//
// If r is a LineReader or StringReader, it is used directly. Otherwise, it is
// wrapped in a way that may read extra data from the underlying input.
func Parse(r io.Reader) ([]*File, string, error) {
p := newParser(r)
@@ -69,8 +67,12 @@ func Parse(r io.Reader) ([]*File, string, error) {
// - if returning an object, advance to the first line after the object
// - any exported parsing methods must initialize the parser by calling Next()
type stringReader interface {
ReadString(delim byte) (string, error)
}
type parser struct {
r LineReader
r stringReader
eof bool
lineno int64
@@ -78,10 +80,10 @@ type parser struct {
}
func newParser(r io.Reader) *parser {
if lr, ok := r.(LineReader); ok {
return &parser{r: lr}
if r, ok := r.(stringReader); ok {
return &parser{r: r}
}
return &parser{r: NewLineReader(r, 0)}
return &parser{r: bufio.NewReader(r)}
}
// Next advances the parser by one line. It returns any error encountered while
@@ -117,7 +119,7 @@ func (p *parser) shiftLines() (err error) {
for i := 0; i < len(p.lines)-1; i++ {
p.lines[i] = p.lines[i+1]
}
p.lines[len(p.lines)-1], _, err = p.r.ReadLine()
p.lines[len(p.lines)-1], err = p.r.ReadString('\n')
return
}