mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-09 15:32:54 +01:00
Closes #11
This PR adds a `Msg.Read()` method which satisfies the `io.Reader` interface
This commit is contained in:
parent
c001ac5b94
commit
dd02ac229b
3 changed files with 78 additions and 1 deletions
|
@ -32,8 +32,9 @@ Some of the features of this library:
|
||||||
* [X] Support for common mail header field generation (Message-ID, Date, Bulk-Precedence, Priority, etc.)
|
* [X] Support for common mail header field generation (Message-ID, Date, Bulk-Precedence, Priority, etc.)
|
||||||
* [X] Reusing the same SMTP connection to send multiple mails
|
* [X] Reusing the same SMTP connection to send multiple mails
|
||||||
* [X] Support for attachments and inline embeds
|
* [X] Support for attachments and inline embeds
|
||||||
* [X] Support for different encodings (existing but not fully tested)
|
* [X] Support for different encodings
|
||||||
* [X] Support sending mails via a local sendmail command
|
* [X] Support sending mails via a local sendmail command
|
||||||
|
* [X] Message object satisfies `io.WriteTo` and `io.Reader` interfaces
|
||||||
|
|
||||||
go-mail works like a programatic email client and provides lots of methods and functionalities you would consider
|
go-mail works like a programatic email client and provides lots of methods and functionalities you would consider
|
||||||
standard in a MUA.
|
standard in a MUA.
|
||||||
|
|
10
msg.go
10
msg.go
|
@ -552,6 +552,16 @@ func (m *Msg) WriteToSendmailWithContext(ctx context.Context, sp string, a ...st
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read outputs the length of p into p to satisfy the io.Reader interface
|
||||||
|
func (m *Msg) Read(p []byte) (int, error) {
|
||||||
|
wbuf := bytes.Buffer{}
|
||||||
|
_, err := m.WriteTo(&wbuf)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("failed to write message to internal write buffer: %w", err)
|
||||||
|
}
|
||||||
|
return wbuf.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
// encodeString encodes a string based on the configured message encoder and the corresponding
|
// encodeString encodes a string based on the configured message encoder and the corresponding
|
||||||
// charset for the Msg
|
// charset for the Msg
|
||||||
func (m *Msg) encodeString(s string) string {
|
func (m *Msg) encodeString(s string) string {
|
||||||
|
|
66
msg_test.go
66
msg_test.go
|
@ -1272,3 +1272,69 @@ func TestMsg_multipleWrites(t *testing.T) {
|
||||||
t.Errorf("second WriteTo() body does not contain unique string: %s", ts)
|
t.Errorf("second WriteTo() body does not contain unique string: %s", ts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestMsg_Read tests the Msg.Read method that implements the io.Reader interface
|
||||||
|
func TestMsg_Read(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
plen int
|
||||||
|
}{
|
||||||
|
{"P length is bigger than the mail", 32000},
|
||||||
|
{"P length is smaller than the mail", 128},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, "TEST123")
|
||||||
|
wbuf := bytes.Buffer{}
|
||||||
|
_, err := m.Write(&wbuf)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to write message into temporary buffer: %s", err)
|
||||||
|
}
|
||||||
|
elen := wbuf.Len()
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
p := make([]byte, tt.plen)
|
||||||
|
n, err := m.Read(p)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to Read(): %s", err)
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
t.Errorf("failed to Read() - received 0 bytes of data")
|
||||||
|
}
|
||||||
|
if tt.plen >= elen && n != elen {
|
||||||
|
t.Errorf("failed to Read() - not all data received. Expected: %d, got: %d", elen, n)
|
||||||
|
}
|
||||||
|
if tt.plen < elen && n != tt.plen {
|
||||||
|
t.Errorf("failed to Read() - full length of p wasn't filled with data. Expected: %d, got: %d",
|
||||||
|
tt.plen, n)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestMsg_Read_ioCopy tests the Msg.Read method using io.Copy
|
||||||
|
func TestMsg_Read_ioCopy(t *testing.T) {
|
||||||
|
wbuf1 := bytes.Buffer{}
|
||||||
|
wbuf2 := bytes.Buffer{}
|
||||||
|
m := NewMsg()
|
||||||
|
m.SetBodyString(TypeTextPlain, "TEST123")
|
||||||
|
|
||||||
|
// First we use WriteTo to have something to compare to
|
||||||
|
_, err := m.WriteTo(&wbuf1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to write body to buffer: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then we write to wbuf2 via io.Copy
|
||||||
|
n, err := io.Copy(&wbuf2, m)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to use io.Copy on Msg: %s", err)
|
||||||
|
}
|
||||||
|
if n != int64(wbuf1.Len()) {
|
||||||
|
t.Errorf("message length of WriteTo and io.Copy differ. Expected: %d, got: %d", wbuf1.Len(), n)
|
||||||
|
}
|
||||||
|
if wbuf1.String() != wbuf2.String() {
|
||||||
|
t.Errorf("message content of WriteTo and io.Copy differ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue