Merge pull request #4 from wneessen/writeto_interface

Rename Write() to WriteTo() so it satisfies the io.WriteTo interface
This commit is contained in:
Winni Neessen 2022-05-24 15:59:09 +02:00 committed by GitHub
commit 82cb089a8b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 19 deletions

View file

@ -359,7 +359,7 @@ func (c *Client) Send(ml ...*Msg) error {
if err != nil { if err != nil {
return fmt.Errorf("sending DATA command failed: %w", err) return fmt.Errorf("sending DATA command failed: %w", err)
} }
_, err = m.Write(w) _, err = m.WriteTo(w)
if err != nil { if err != nil {
return fmt.Errorf("sending mail content failed: %w", err) return fmt.Errorf("sending mail content failed: %w", err)
} }

2
doc.go
View file

@ -2,4 +2,4 @@
package mail package mail
// VERSION is used in the default user agent string // VERSION is used in the default user agent string
const VERSION = "0.1.8" const VERSION = "0.1.9"

11
msg.go
View file

@ -460,13 +460,18 @@ func (m *Msg) Reset() {
m.parts = nil m.parts = nil
} }
// Write writes the formated Msg into a give io.Writer // WriteTo writes the formated Msg into a give io.Writer and satisfies the io.WriteTo interface
func (m *Msg) Write(w io.Writer) (int64, error) { func (m *Msg) WriteTo(w io.Writer) (int64, error) {
mw := &msgWriter{w: w, c: m.charset, en: m.encoder} mw := &msgWriter{w: w, c: m.charset, en: m.encoder}
mw.writeMsg(m) mw.writeMsg(m)
return mw.n, mw.err return mw.n, mw.err
} }
// Write is an alias method to WriteTo due to compatiblity reasons
func (m *Msg) Write(w io.Writer) (int64, error) {
return m.WriteTo(w)
}
// appendFile adds a File to the Msg (as attachment or embed) // appendFile adds a File to the Msg (as attachment or embed)
func (m *Msg) appendFile(c []*File, f *File, o ...FileOption) []*File { func (m *Msg) appendFile(c []*File, f *File, o ...FileOption) []*File {
// Override defaults with optionally provided FileOption functions // Override defaults with optionally provided FileOption functions
@ -525,7 +530,7 @@ func (m *Msg) WriteToSendmailWithContext(ctx context.Context, sp string, a ...st
if err := ec.Start(); err != nil { if err := ec.Start(); err != nil {
return fmt.Errorf("could not start sendmail execution: %w", err) return fmt.Errorf("could not start sendmail execution: %w", err)
} }
_, err = m.Write(si) _, err = m.WriteTo(si)
if err != nil { if err != nil {
if !errors.Is(err, syscall.EPIPE) { if !errors.Is(err, syscall.EPIPE) {
return fmt.Errorf("failed to write mail to buffer: %w", err) return fmt.Errorf("failed to write mail to buffer: %w", err)

View file

@ -1123,6 +1123,21 @@ func TestMsg_hasMixed(t *testing.T) {
} }
} }
// TestMsg_WriteTo tests the WriteTo() method of the Msg
func TestMsg_WriteTo(t *testing.T) {
m := NewMsg()
m.SetBodyString(TypeTextPlain, "Plain")
wbuf := bytes.Buffer{}
n, err := m.WriteTo(&wbuf)
if err != nil {
t.Errorf("WriteTo() failed: %s", err)
return
}
if n != int64(wbuf.Len()) {
t.Errorf("WriteTo() failed: expected written byte length: %d, got: %d", n, wbuf.Len())
}
}
// TestMsg_Write tests the Write() method of the Msg // TestMsg_Write tests the Write() method of the Msg
func TestMsg_Write(t *testing.T) { func TestMsg_Write(t *testing.T) {
m := NewMsg() m := NewMsg()
@ -1130,15 +1145,15 @@ func TestMsg_Write(t *testing.T) {
wbuf := bytes.Buffer{} wbuf := bytes.Buffer{}
n, err := m.Write(&wbuf) n, err := m.Write(&wbuf)
if err != nil { if err != nil {
t.Errorf("Write() failed: %s", err) t.Errorf("WriteTo() failed: %s", err)
return return
} }
if n != int64(wbuf.Len()) { if n != int64(wbuf.Len()) {
t.Errorf("Write() failed: expected written byte length: %d, got: %d", n, wbuf.Len()) t.Errorf("WriteTo() failed: expected written byte length: %d, got: %d", n, wbuf.Len())
} }
} }
// TestMsg_WriteWithLongHeader tests the Write() method of the Msg with a long header // TestMsg_WriteWithLongHeader tests the WriteTo() method of the Msg with a long header
func TestMsg_WriteWithLongHeader(t *testing.T) { func TestMsg_WriteWithLongHeader(t *testing.T) {
m := NewMsg() m := NewMsg()
m.SetBodyString(TypeTextPlain, "Plain") m.SetBodyString(TypeTextPlain, "Plain")
@ -1147,17 +1162,17 @@ func TestMsg_WriteWithLongHeader(t *testing.T) {
m.SetHeader(HeaderContentID, "XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX", m.SetHeader(HeaderContentID, "XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXX") "XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXX")
wbuf := bytes.Buffer{} wbuf := bytes.Buffer{}
n, err := m.Write(&wbuf) n, err := m.WriteTo(&wbuf)
if err != nil { if err != nil {
t.Errorf("Write() failed: %s", err) t.Errorf("WriteTo() failed: %s", err)
return return
} }
if n != int64(wbuf.Len()) { if n != int64(wbuf.Len()) {
t.Errorf("Write() failed: expected written byte length: %d, got: %d", n, wbuf.Len()) t.Errorf("WriteTo() failed: expected written byte length: %d, got: %d", n, wbuf.Len())
} }
} }
// TestMsg_WriteDiffEncoding tests the Write() method of the Msg with different Encoding // TestMsg_WriteDiffEncoding tests the WriteTo() method of the Msg with different Encoding
func TestMsg_WriteDiffEncoding(t *testing.T) { func TestMsg_WriteDiffEncoding(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
@ -1200,13 +1215,13 @@ func TestMsg_WriteDiffEncoding(t *testing.T) {
m.EmbedFile("README.md") m.EmbedFile("README.md")
} }
wbuf := bytes.Buffer{} wbuf := bytes.Buffer{}
n, err := m.Write(&wbuf) n, err := m.WriteTo(&wbuf)
if err != nil { if err != nil {
t.Errorf("Write() failed: %s", err) t.Errorf("WriteTo() failed: %s", err)
return return
} }
if n != int64(wbuf.Len()) { if n != int64(wbuf.Len()) {
t.Errorf("Write() failed: expected written byte length: %d, got: %d", n, wbuf.Len()) t.Errorf("WriteTo() failed: expected written byte length: %d, got: %d", n, wbuf.Len())
} }
wbuf.Reset() wbuf.Reset()
}) })

View file

@ -279,7 +279,7 @@ func (mw *msgWriter) writeBody(f func(io.Writer) (int64, error), e Encoding) {
mw.err = ew.Close() mw.err = ew.Close()
n, mw.err = io.Copy(w, &wbuf) n, mw.err = io.Copy(w, &wbuf)
// Since the part writer uses the Write() method, we don't need to add the // Since the part writer uses the WriteTo() method, we don't need to add the
// bytes twice // bytes twice
if mw.d == 0 { if mw.d == 0 {
mw.n += n mw.n += n

View file

@ -21,20 +21,20 @@ func (bw *brokenWriter) Write([]byte) (int, error) {
return 0, fmt.Errorf("intentionally failed") return 0, fmt.Errorf("intentionally failed")
} }
// TestMsgWriter_Write tests the Write() method of the msgWriter // TestMsgWriter_Write tests the WriteTo() method of the msgWriter
func TestMsgWriter_Write(t *testing.T) { func TestMsgWriter_Write(t *testing.T) {
bw := &brokenWriter{} bw := &brokenWriter{}
mw := &msgWriter{w: bw, c: CharsetUTF8, en: mime.QEncoding} mw := &msgWriter{w: bw, c: CharsetUTF8, en: mime.QEncoding}
_, err := mw.Write([]byte("test")) _, err := mw.Write([]byte("test"))
if err == nil { if err == nil {
t.Errorf("msgWriter Write() with brokenWriter should fail, but didn't") t.Errorf("msgWriter WriteTo() with brokenWriter should fail, but didn't")
} }
// Also test the part when a previous error happened // Also test the part when a previous error happened
mw.err = fmt.Errorf("broken") mw.err = fmt.Errorf("broken")
_, err = mw.Write([]byte("test")) _, err = mw.Write([]byte("test"))
if err == nil { if err == nil {
t.Errorf("msgWriter Write() with brokenWriter should fail, but didn't") t.Errorf("msgWriter WriteTo() with brokenWriter should fail, but didn't")
} }
} }