Rust邮件构建库mail-builder的使用:高效创建和解析符合RFC标准的电子邮件

Rust邮件构建库mail-builder的使用:高效创建和解析符合RFC标准的电子邮件

mail-builder是一个用Rust编写的灵活电子邮件构建库,具有以下特性:

  • 生成符合互联网消息格式标准(RFC 5322)的电子邮件消息
  • 完整的MIME支持(RFC 2045 - 2049),自动为每个消息正文部分选择最优编码
  • 基于Chromium解码器的快速Base64编码(最快的非SIMD编码器)
  • 无依赖(gethostname是可选的)

请注意,这个库不支持发送或解析电子邮件消息,这些功能由mail-sendmail-parser这两个crate提供。

使用示例

基本示例

构建一个带有文本正文和一个附件的简单电子邮件消息:

// 构建一个带有单个附件的简单文本消息
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_ref())
    .write_to_string()
    .unwrap();
    
// 打印原始消息
println!("{}", eml);

复杂示例

构建带有分组地址、内联部分和多部分/替代部分的复杂消息:

// 构建带有文本和HTML正文、内联部分和附件的多部分消息
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收件人
    .bcc(vec![
        (
            "My Group",
            vec![
                ("ASCII name", "addr1@addr7.com"),
                ("ハロー・ワールド", "addr2@addr6.com"),
                ("áéíóú", "addr3@addr5.com"),
                ("Γειά σου Κόσμε", "addr4@addr4.com"),
            ],
        ),
        (
            "Another Group",
            vec![
                ("שלום עולם", "addr5@addr3.com"),
                ("ñandú come ñoquis", "addr6@addr2.com"),
                ("Recipient", "addr7@addr1.com"),
            ],
        ),
    ])

    // 设置RFC和自定义头
    .subject("Testing multipart messages") 
    .in_reply_to(vec!["message-id-1", "message-id-2"])
    .header("List-Archive", URL::new("http://example.com/archive"))

    // 设置HTML和纯文本正文
    .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_ref())
    .attachment("text极好的!让我们来详细分析这个Rust邮件构建库mail-builder的使用方法。根据您提供的内容,我将整理出完整的示例代码和说明。

## 完整示例代码

```rust
use mail_builder::MessageBuilder;
use mail_builder::headers::address::Address;
use mail_builder::headers::URL;
use mail_builder::mime::MimePart;
use std::fs::File;

fn main() {
    // 示例1:简单消息
    let simple_msg = MessageBuilder::new()
        .from(("John Doe", "john@doe.com"))
        .to("jane@doe.com")
        .subject("Simple message")
        .text_body("This is a simple message with one attachment.")
        .attachment("text/plain", "hello.txt", b"Hello, world!".as_ref())
        .write_to_string()
        .unwrap();
    
    println!("Simple message:\n{}\n", simple_msg);

    // 示例2:复杂消息
    let complex_msg = MessageBuilder::new()
        .from(("Sender Name", "sender@example.com"))
        .to(vec![
            ("Recipient 1", "recipient1@example.com"),
            ("Recipient 2", "recipient2@example.com"),
        ])
        .subject("Complex message with HTML and attachments")
        .text_body("Plain text version of the message")
        .html_body("<p>HTML version with <b>formatting</b> and <img src=\"cid:logo\"/></p>")
        .inline("image/png", "cid:logo", include_bytes!("logo.png").as_ref())
        .attachment(
            "application/pdf",
            "document.pdf",
            include_bytes!("document.pdf").as_ref(),
        )
        .write_to_string()
        .unwrap();
    
    println!("Complex message:\n{}\n", complex_msg);

    // 示例3:写入文件
    MessageBuilder::new()
        .from(("File Writer", "file@example.com"))
        .to("recipient@example.com")
        .subject("Message saved to file")
        .text_body("This message will be saved to a file.")
        .write_to(File::create("output.eml").unwrap())
        .unwrap();
    
    println!("Message saved to output.eml");
}

测试方法

要运行测试套件:

$ cargo test --all-features

或者使用MIRI运行测试套件:

$ cargo +nightly miri test --all-features

许可证信息

根据以下任一许可证授权:

  • Apache License, Version 2.0
  • MIT license

版权声明

版权所有 © 2020, Stalwart Labs LLC


1 回复

Rust邮件构建库mail-builder使用指南

mail-builder是一个用于构建和解析符合RFC标准电子邮件的Rust库。它提供了简单直观的API来创建各种类型的电子邮件,包括文本邮件、HTML邮件以及带附件的多部分邮件。

基本用法

首先在Cargo.toml中添加依赖:

[dependencies]
mail-builder = "0.3"

创建简单文本邮件

use mail_builder::MessageBuilder;

// 创建一个简单的文本邮件
let email = MessageBuilder::new()
    .from("John Doe <john@example.com>")  // 设置发件人
    .to("Jane Smith <jane@example.com>")  // 设置收件人
    .subject("Hello from Rust!")          // 设置邮件主题
    .text_body("This is a plain text email body.")  // 设置纯文本正文
    .build()
    .unwrap();

println!("{}", email);  // 打印生成的邮件内容

创建HTML邮件

// 创建一个HTML格式的邮件
let email = MessageBuilder::new()
    .from("John Doe <john@example.com>")
    .to("Jane Smith <jane@example.com>")
    .subject("HTML Email")
    .html_body("<h1>Hello!</h1><p>This is an <strong>HTML</strong> email.</p>")  // 设置HTML正文
    .build()
    .unwrap();

创建带附件的邮件

use mail_builder::headers::content_type::MediaType;
use std::fs;

// 读取附件文件内容
let attachment_data = fs::read("document.pdf").unwrap();

// 创建带附件的邮件
let email = MessageBuilder::new()
    .from("sender@example.com")
    .to("recipient@example.com")
    .subject("Email with attachment")
    .text_body("Please see the attached document.")
    .binary_attachment(
        MediaType::parse("application/pdf").unwrap(),  // 设置附件MIME类型
        "document.pdf",  // 设置附件文件名
        &attachment_data,  // 设置附件数据
    )
    .build()
    .unwrap();

创建多部分邮件(文本+HTML+附件)

// 创建包含文本、HTML和附件的多部分邮件
let email = MessageBuilder::new()
    .from("sender@example.com")
    .to("recipient@example.com")
    .subject("Multipart email")
    .text_body("This is the plain text version.")  // 纯文本版本
    .html_body("<h1>HTML version</h1><p>This is the HTML version.</p>")  // HTML版本
    .binary_attachment(
        MediaType::parse("application/pdf").unwrap(),
        "document.pdf",
        &attachment_data,
    )
    .build()
    .unwrap();

解析邮件

mail-builder也可以用于解析现有的电子邮件:

use mail_parser::Message;

// 原始邮件字符串
let raw_email = "From: sender@example.com\r\n\
                To: recipient@example.com\r\n\
                Subject: Test\r\n\
                \r\n\
                This is the body";

// 解析邮件
let message = Message::parse(raw_email.as_bytes()).unwrap();

// 打印解析结果
println!("From: {:?}", message.from());
println!("Subject: {:?}", message.subject());
println!("Body: {:?}", message.body_text(0));

高级功能

  1. 自定义头信息
// 添加自定义邮件头
let email = MessageBuilder::new()
    .from("sender@example.com")
    .to("recipient@example.com")
    .header("X-Custom-Header", "Some value")  // 自定义头
    .subject("Custom headers")
    .text_body("This email has custom headers.")
    .build()
    .unwrap();
  1. 抄送和密送
// 设置抄送(CC)和密送(BCC)
let email = MessageBuilder::new()
    .from("sender@example.com")
    .to("primary@example.com")  // 主收件人
    .cc("cc@example.com")       // 抄送
    .bcc("bcc@example.com")     // 密送
    .subject("CC and BCC example")
    .text_body("This email demonstrates CC and BCC.")
    .build()
    .unwrap();
  1. 内联图片
// 读取图片数据
let image_data = fs::read("image.png").unwrap();

// 创建带内联图片的邮件
let email = MessageBuilder::new()
    .from("sender@example.com")
    .to("recipient@example.com")
    .subject("Email with inline image")
    .html_body("<h1>Hello!</h1><img src=\"cid:image1\">")  // 使用cid引用图片
    .inline_binary(
        MediaType::parse("image/png").unwrap(),  // 图片MIME类型
        "image1",  // 图片cid
        &image_data,  // 图片数据
    )
    .build()
    .unwrap();

注意事项

  1. 确保所有地址都符合RFC标准格式
  2. 对于生产环境,考虑添加DKIM签名和其他安全头信息
  3. 大附件可能需要流式处理而不是一次性加载到内存

mail-builder库提供了构建符合RFC标准的电子邮件的强大功能,同时保持了简单易用的API设计。

完整示例代码

以下是一个完整的示例,展示如何使用mail-builder创建并发送一封包含文本、HTML和内联图片的邮件:

use mail_builder::MessageBuilder;
use mail_builder::headers::content_type::MediaType;
use std::fs;

fn main() {
    // 读取图片数据
    let image_data = match fs::read("logo.png") {
        Ok(data) => data,
        Err(e) => {
            eprintln!("Error reading image file: {}", e);
            return;
        }
    };

    // 构建邮件
    let email = MessageBuilder::new()
        .from("Company <noreply@company.com>")
        .to("Customer <customer@example.com>")
        .subject("Your Monthly Newsletter")
        .text_body("Thank you for subscribing to our newsletter!")
        .html_body(r#"
            <h1>Monthly Newsletter</h1>
            <p>Thank you for subscribing to our newsletter!</p>
            <p>Here is our logo: <img src="cid:company_logo"></p>
        "#)
        .inline_binary(
            MediaType::parse("image/png").unwrap(),
            "company_logo",
            &image_data,
        )
        .build()
        .expect("Failed to build email");

    println!("Generated email:\n{}", email);
    
    // 在实际应用中,这里可以添加发送邮件的代码
    // 例如使用SMTP库发送构建好的邮件
}

这个示例展示了如何:

  1. 读取本地图片文件作为内联图片
  2. 创建包含文本和HTML版本的多部分邮件
  3. 在HTML中通过cid引用内联图片
  4. 构建完整的邮件内容

在实际应用中,你还需要使用SMTP库(如lettre)来发送构建好的邮件。

回到顶部