Skip to main content

Crate mail_builder

Crate mail_builder 

Source
Expand description

mail_builder is a flexible e-mail builder written in Rust. It includes the following features:

  • Generates messages conforming to the Internet Message Format standard (RFC 5322).
  • Full MIME support (RFC 2045 – 2049) with automatic selection of the most optimal transfer encoding for each body part.
  • RFC 2047 encoded words and RFC 2231 extended parameters for non-ASCII subjects, names and file names, folded to comply with the 78-column recommendation (and the 998-column limit).
  • Header values are sanitised: control characters and CR/LF that could inject extra header fields are removed or encoded before they reach the output.
  • MIME boundaries are random and are checked against the part contents.
  • No unsafe, no external dependencies.

This library builds messages; it does not send or parse them.

§Usage

Build a simple e-mail message with a text body and one attachment:

use mail_builder::MessageBuilder;

// Build a simple text message with a single attachment
let eml = MessageBuilder::new()
    .from(("John Doe", "john@doe.com"))
    .to("jane@doe.com")
    .subject("Hello, world!")
    .text_body("Message contents go here.")
    .attachment("image/png", "image.png", [1, 2, 3, 4].as_slice())
    .to_string()
    .unwrap();

// Print raw message
println!("{eml}");

More complex messages with grouped addresses, inline parts and multipart/alternative sections can also be built:

use mail_builder::{MessageBuilder, headers::url::URL};
use std::fs::File;

// Build a multipart message with text and HTML bodies, inline parts and
// attachments.
MessageBuilder::new()
    .from(("John Doe", "john@doe.com"))
    .to(vec![
        ("Antoine de Saint-Exupéry", "antoine@exupery.com"),
        ("안녕하세요 세계", "test@test.com"),
        ("Xin chào", "addr@addr.com"),
    ])
    .bcc(vec![(
        "My Group",
        vec![
            ("ASCII name", "addr1@addr7.com"),
            ("ハロー・ワールド", "addr2@addr6.com"),
        ],
    )])
    .subject("Testing multipart messages")
    .in_reply_to(vec!["message-id-1", "message-id-2"])
    .header("List-Archive", URL::new("http://example.com/archive"))
    .text_body("This is the text body!\n")
    .html_body("<p>HTML body with <img src=\"cid:my-image\"/>!</p>")
    .inline("image/png", "cid:my-image", [0, 1, 2, 3, 4, 5].as_slice())
    .attachment("text/plain", "my fíle.txt", "Attachment contents go here.")
    .attachment(
        "text/plain",
        "ハロー・ワールド",
        b"Binary contents go here.".as_slice(),
    )
    .write_to(File::create("message.eml").unwrap())
    .unwrap();

Nested MIME body structures can be created using the body method:

use mail_builder::{MessageBuilder, headers::address::Address, mime::MimePart};
use std::fs::File;

MessageBuilder::new()
    .from(Address::new_address("John Doe".into(), "john@doe.com"))
    .to(Address::new_address("Jane Doe".into(), "jane@doe.com"))
    .subject("Nested multipart message")
    .body(MimePart::new(
        "multipart/mixed",
        vec![
            MimePart::new("text/plain", "Part A contents go here...").inline(),
            MimePart::new(
                "multipart/alternative",
                vec![
                    MimePart::new("text/plain", "Part B contents go here...").inline(),
                    MimePart::new("text/html", "<p>Part C contents go here...</p>").inline(),
                ],
            ),
            MimePart::new("image/jpeg", "Part D contents go here...".as_bytes())
                .attachment("image_D.jpg"),
        ],
    ))
    .write_to(File::create("nested-message.eml").unwrap())
    .unwrap();

§Notes

  • Text values are written as 7bit when possible, otherwise as quoted-printable or Base64, whichever is shorter. Bare CR/LF in a body are normalised to CRLF.
  • Raw header values are the only escape hatch: they are folded but otherwise written as given, so callers are responsible for their contents.
  • Generated Message-ID headers use a fixed localhost domain instead of the machine’s host name, so building a message never leaks the local host name.

Re-exports§

pub use writer::IoWriter;
pub use writer::Writer;

Modules§

headers
mime
writer

Structs§

MessageBuilder
Builds an RFC5322 compliant MIME email message.