Skip to content

Commit

Permalink
update configurable line terminators implementation
Browse files Browse the repository at this point in the history
update configurable line terminators implementation to better align with
the rest of the code base.
  • Loading branch information
ianlopshire committed Oct 11, 2019
1 parent 6ae718e commit e38e297
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 35 deletions.
22 changes: 12 additions & 10 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,25 @@ func (e *MarshalInvalidTypeError) Error() string {
// An Encoder writes fixed-width formatted data to an output
// stream.
type Encoder struct {
w *bufio.Writer

LineEnd []byte
w *bufio.Writer
lineTerminator []byte
}

// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{
w: bufio.NewWriter(w),
LineEnd: []byte("\n"),
w: bufio.NewWriter(w),
lineTerminator: []byte("\n"),
}
}

// SetLineTerminator sets the character(s) that will be used to terminate lines.
//
// The default value is "\n".
func (e *Encoder) SetLineTerminator(lineTerminator []byte) {
e.lineTerminator = lineTerminator
}

// Encode writes the fixed-width encoding of v to the
// stream.
// See the documentation for Marshal for details about
Expand Down Expand Up @@ -98,18 +104,14 @@ func (e *Encoder) Encode(i interface{}) (err error) {
}

func (e *Encoder) writeLines(v reflect.Value) error {
lineEnd := e.LineEnd
if len(lineEnd) == 0 {
lineEnd = []byte("\n")
}
for i := 0; i < v.Len(); i++ {
err := e.writeLine(v.Index(i))
if err != nil {
return err
}

if i != v.Len()-1 {
_, err := e.w.Write(lineEnd)
_, err := e.w.Write(e.lineTerminator)
if err != nil {
return err
}
Expand Down
38 changes: 13 additions & 25 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package fixedwidth
import (
"bytes"
"fmt"
"io"
"log"
"reflect"
"testing"
Expand Down Expand Up @@ -129,34 +128,23 @@ func TestNewValueEncoder(t *testing.T) {
}
}

func TestEncoderWithMultipleLines(t *testing.T) {
func TestEncoder_SetLineTerminator(t *testing.T) {
buff := new(bytes.Buffer)
enc := NewEncoder(buff)
enc.SetLineTerminator([]byte{'\r', '\n'})

input := []interface{}{
EncodableString{"foo", nil},
EncodableString{"bar", nil},
}

for _, tt := range []struct {
name string
expected string
newEncoder func(io.Writer) *Encoder
}{
{"default", "foo\nbar", func(w io.Writer) *Encoder { return NewEncoder(w) }},
{"default", "foo\r\nbar", func(w io.Writer) *Encoder {
enc := NewEncoder(w)
enc.LineEnd = []byte("\r\n")
return enc
}},
} {
t.Run(tt.name, func(t *testing.T) {
var buf bytes.Buffer
enc := tt.newEncoder(&buf)
err := enc.Encode(input)
if err != nil {
t.Fatal(err)
}
if buf.String() != tt.expected {
t.Fatalf("unexpected output\nexpected: %q\nreceived: %q", tt.expected, buf.String())
}
})
err := enc.Encode(input)
if err != nil {
t.Fatal("Encode() unexpected error")
}

expected := []byte("foo\r\nbar")
if !bytes.Equal(expected, buff.Bytes()) {
t.Errorf("Encode() expected %q, have %q", expected, buff.Bytes())
}
}

0 comments on commit e38e297

Please sign in to comment.