email_address

An RFC 5322-compliant EmailAddress newtype for parsing and validating email addresses in Rust.

Library
Cargo
v0.2.9
94stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
36/100Needs Attention
Development Activity0
Maintenance20
Community44
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture70
Code Quality85
Innovation85
Learning Curve80

email_address provides a strongly-typed EmailAddress wrapper around String, built specifically for validating and working with email addresses per the relevant IETF specifications (RFC 1123, 3629, 3696, 4291, 5234, 5321, 5322, 5890, 6531, 6532). Addresses are constructed exclusively through FromStr::from_str or parse_with_options, which run the full local-part and domain grammar checks and return a typed Error enum on failure rather than a boolean or panic.

Beyond ASCII, the crate supports UTF-8 local parts and domains (internationalized addresses), quoted local parts, domain literals (IPv4/IPv6 in brackets), and optional display-name parsing ("Name <user@example.com>"). An Options struct exposes chainable builder methods for relaxing or tightening RFC edge cases, such as requiring a minimum number of domain segments or disallowing domain literals, so consumers can match their own validation policy without forking the parser.

What You Get

  • A typed EmailAddress newtype that can only be constructed from a string that has already passed RFC-grammar validation.
  • Static is_valid, is_valid_local_part, and is_valid_domain helpers for pre-construction checks without allocating.
  • A configurable Options builder for relaxing/tightening RFC edge cases: minimum sub-domains, domain literals, and display-name support.
  • Accessors for the parsed components — local_part(), domain(), email(), display_part() — plus to_uri() for mailto: links and to_display() for Name <user@example.com> formatting.
  • Optional serde support (on by default via the serde_support feature) for serializing/deserializing EmailAddress as a plain string.

Common Use Cases

  • Validating email addresses submitted through a web form or API before persisting them.
  • Parsing addresses from mailto: links or email headers into their component parts.
  • Enforcing stricter-than-default rules (e.g. requiring a TLD) on user-submitted addresses via Options.
  • Deserializing untrusted JSON/config input into a guaranteed-valid EmailAddress type via serde.

Under The Hood

Architecture The crate is implemented as a single src/lib.rs file (~1,900 lines including its extensive test suite) following a newtype-wrapper pattern: EmailAddress(String) can only be built through FromStr::from_str or parse_with_options, both of which funnel into parse_addresssplit_partsparse_local_part/parse_domain → character-class predicate functions (is_atext, is_qtext_char, is_dtext_char). There is no internal module layering beyond public API surface, parsing internals, and character predicates — a deliberate flat structure for a narrowly scoped grammar validator, where the Options struct and predicate functions are the load-bearing abstraction and any RFC-rule change touches them directly.

Tech Stack Pure Rust (edition 2018) with zero required runtime dependencies. The only dependency is optional serde ~1.0, gated behind the default-on serde_support feature for Serialize/Deserialize. Dev-dependencies (claims 0.8, serde_assert 0.8) support test assertions and serde round-trip testing. Build tooling is plain cargo; the crate publishes to crates.io with docs.rs configured for a single target (x86_64-unknown-linux-gnu). No web framework, database, or external service integration — this is a leaf utility crate.

Code Quality The test module contains dozens of table-driven test cases covering Wikipedia’s canonical valid/invalid email examples, multi-script Unicode local parts (Chinese, Hindi, Ukrainian, Greek, German, Russian), Options-driven parsing variants, and case-sensitivity/equality semantics, plus a separate serde_tests module for serialization round-trips. Error handling is fully typed through a dedicated Error enum implementing std::error::Error, Display, Clone, and PartialEq — the public API never panics or swallows a validation failure. The crate opts into strict lint groups (#![warn(missing_docs, unreachable_pub, rust_2018_idioms, ...)]) and denies unsafe code and several deprecated patterns. CI runs both a build workflow and a dedicated security-audit workflow.

API Design The public surface is intentionally minimal: construct via the standard FromStr trait, or use is_valid/is_valid_local_part/is_valid_domain for pre-construction checks. The Options type uses chainable, const fn builder methods (with_minimum_sub_domains, without_domain_literal, with_display_text, etc.) so callers can express a validation policy declaratively. Component accessors (local_part, domain, email, display_part) avoid extra allocation by borrowing from the original string, and nearly every public method carries a runnable doctest, keeping the crate’s documentation and its guarantees in sync.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search