diff --git a/msg.go b/msg.go index bfb521d..d644d0a 100644 --- a/msg.go +++ b/msg.go @@ -42,9 +42,14 @@ const ( errParseMailAddr = "failed to parse mail address %q: %w" ) +// MiddlewareType is the type description of the Middleware and needs to be returned +// in the Middleware interface by the Type method +type MiddlewareType string + // Middleware is an interface to define a function to apply to Msg before sending type Middleware interface { Handle(*Msg) *Msg + Type() MiddlewareType } // Msg is the mail message struct @@ -713,6 +718,24 @@ func (m *Msg) WriteTo(w io.Writer) (int64, error) { return mw.n, mw.err } +// WriteToSkipMiddleware writes the formated Msg into a give io.Writer and satisfies +// the io.WriteTo interface but will skip the given Middleware +func (m *Msg) WriteToSkipMiddleware(w io.Writer, mt MiddlewareType) (int64, error) { + var omwl, mwl []Middleware + omwl = m.middlewares + for i := range m.middlewares { + if m.middlewares[i].Type() == mt { + continue + } + mwl = append(mwl, m.middlewares[i]) + } + m.middlewares = mwl + mw := &msgWriter{w: w, c: m.charset, en: m.encoder} + mw.writeMsg(m.applyMiddlewares(m)) + m.middlewares = omwl + return mw.n, mw.err +} + // Write is an alias method to WriteTo due to compatibility reasons func (m *Msg) Write(w io.Writer) (int64, error) { return m.WriteTo(w) diff --git a/msg_test.go b/msg_test.go index 0abb724..7fa7a05 100644 --- a/msg_test.go +++ b/msg_test.go @@ -189,6 +189,10 @@ func (mw uppercaseMiddleware) Handle(m *Msg) *Msg { return m } +func (mw uppercaseMiddleware) Type() MiddlewareType { + return "uppercase" +} + type encodeMiddleware struct{} func (mw encodeMiddleware) Handle(m *Msg) *Msg { @@ -200,6 +204,10 @@ func (mw encodeMiddleware) Handle(m *Msg) *Msg { return m } +func (mw encodeMiddleware) Type() MiddlewareType { + return "encode" +} + // TestNewMsgWithMiddleware tests WithMiddleware func TestNewMsgWithMiddleware(t *testing.T) { m := NewMsg() @@ -1584,6 +1592,38 @@ func TestMsg_WriteTo(t *testing.T) { } } +// TestMsg_WriteTo tests the WriteTo() method of the Msg +func TestMsg_WriteToSkipMiddleware(t *testing.T) { + m := NewMsg(WithMiddleware(encodeMiddleware{}), WithMiddleware(uppercaseMiddleware{})) + m.Subject("This is a test") + m.SetBodyString(TypeTextPlain, "Plain") + wbuf := bytes.Buffer{} + n, err := m.WriteToSkipMiddleware(&wbuf, "uppercase") + if err != nil { + t.Errorf("WriteToSkipMiddleware() failed: %s", err) + return + } + if n != int64(wbuf.Len()) { + t.Errorf("WriteToSkipMiddleware() failed: expected written byte length: %d, got: %d", n, wbuf.Len()) + } + if !strings.Contains(wbuf.String(), "Subject: This is @ test") { + t.Errorf("WriteToSkipMiddleware failed. Unable to find encoded subject") + } + + wbuf2 := bytes.Buffer{} + n, err = m.WriteTo(&wbuf2) + if err != nil { + t.Errorf("WriteTo() failed: %s", err) + return + } + if n != int64(wbuf2.Len()) { + t.Errorf("WriteTo() failed: expected written byte length: %d, got: %d", n, wbuf2.Len()) + } + if !strings.Contains(wbuf2.String(), "Subject: THIS IS @ TEST") { + t.Errorf("WriteToSkipMiddleware failed. Unable to find encoded and upperchase subject") + } +} + // TestMsg_Write tests the Write() method of the Msg func TestMsg_Write(t *testing.T) { m := NewMsg()