envelopwd 0.1.0

A robust, lightweight library for parsing and validating email addresses and mailboxes with sqlx and lettre integration.
Documentation

envelopwd

Crate Docs License

envelopwd is a robust, lightweight Rust library for parsing, validating, and manipulating email addresses and mailboxes.

It was created to address limitations encountered while using the email_address crate - particularly the lack of sqlx integration and the fact that both plain email addresses and name-addr formats were parsed into the same type, which can be awkward in certain contexts.

This crate provides a cleaner separation between address types, adds sqlx support, and introduces additional functionality aimed at improving ergonomics and practical usability.

A significant portion of the parsing logic and test coverage was inspired by and adapted from email_address. Many thanks to its authors for building such a solid and well-tested foundation.

Features

  • Strict Validation: Checks local-part and domain lengths, character sets, and subdomain formatting.
  • Mailbox Support: Easily parse "Name email@example.com" formats.
  • Serialization: Optional Serde support for easy integration with JSON and other formats.
  • Internationalization: Supports non-ASCII characters in local parts and domains (UTF-8).
  • Zero Dependencies: Uses only thiserror for clean error reporting.
  • URI Encoding: Built-in support for converting email addresses to mailto: links.
  • Case Sensitivity Awareness: Properly handles case-insensitive domains while preserving the (rarely used but valid) case sensitivity of local parts.

Installation

Add this to your Cargo.toml:

[dependencies]
envelopwd = "0.1"

To enable optional features like Serde or sqlx, use:

[dependencies]
envelopwd = { version = "0.1", features = ["serde", "sqlx"] }

Quick Start

Validating and Parsing an Email

use envelopwd::EmailAddress;
use std::str::FromStr;

fn main() -> Result<(), envelopwd::Error> {
    // Parse an address
    let addr = EmailAddress::from_str("alice@example.org")?;
    
    println!("User: {}", addr.user());     // alice
    println!("Domain: {}", addr.domain()); // example.org
    
    // Convert to a mailto: URI
    println!("URI: {}", addr.to_uri());    // mailto:alice@example.org
    
    Ok(())
}

Working with Mailboxes (Names + Emails)

use envelopwd::Mailbox;
use std::str::FromStr;

fn main() {
    let input = "John Doe <john.doe@example.com>";
    let mailbox = Mailbox::from_str(input).unwrap();
    
    assert_eq!(mailbox.name(), Some("John Doe"));
    assert_eq!(mailbox.email().user(), "john.doe");
    
    // Display back to string
    println!("{}", mailbox); // John Doe <john.doe@example.com>
}

Optional Features

Serialization with Serde

When the serde feature is enabled, both EmailAddress and Mailbox implement Serialize and Deserialize. They are treated as transparent strings, ensuring they integrate seamlessly with web APIs and configuration files.

use envelopwd::EmailAddress;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct User {
    name: String,
    email: EmailAddress,
}

Database Integration with sqlx

Enable the sqlx feature to use EmailAddress and Mailbox directly in your database models.

Postgres arrays

Enable the sqlx_postgres feature to use EmailAddress and Mailbox in array queries.

Lettre Integration

Enable the lettre feature to allow converting types to their lettre counterparts:

let addr = EmailAddress::from_str("alice@example.org")?;
let lettre_addr: lettre::Address = addr.try_into()?;

let mb = Mailbox::from_str("Alice <alice@example.org>")?;
let lettre_mb: lettre::message::Mailbox = mb.try_into()?;

Validation Logic

envelopwd ensures:

  1. Lengths: Local part ≤ 64 octets, Domain ≤ 254 octets.
  2. Subdomains: Each label is ≤ 63 characters and follows DNS-style alphanumeric rules.
  3. Quoted Parts: Supports quoted local parts (e.g., "john..doe"@example.org).
  4. Literals: Supports domain literals (e.g., jsmith@[192.168.2.1]).

License

This project is licensed under Apache-2.0