email_transport/lib.rs
1//! Core transport traits and per-send option types.
2//!
3//! `Transport` models implementations that accept structured
4//! [`email_message::Message`] values, while `RawTransport` models
5//! implementations that send an explicit envelope plus RFC822 bytes.
6//! Provider-specific options are carried through [`TransportOptions`] so the
7//! core API stays transport-agnostic.
8//!
9//! Terminology:
10//!
11//! - A *transport* is the Rust abstraction/implementation used to send mail.
12//! - A *provider* is the external service or protocol identity behind a
13//! transport, such as `"resend"`, `"postmark"`, or `"smtp"`.
14//! - An *instance* is one configured use of a provider, such as
15//! `"transactional"` or `"marketing"`.
16//!
17//! # Adapter helpers (public API)
18//!
19//! Several utility functions are deliberately public so adapter crates can
20//! share kernel logic without re-implementing it. They are part of the 1.0
21//! semver surface:
22//!
23//! - [`accepted_recipient_emails`], derive the `To + Cc + Bcc` envelope
24//! recipient list from a [`Message`].
25//! - [`structured_accepted_for`], populate [`SendReport::accepted`] in a
26//! structured-`Transport` adapter, honoring a [`SendOptions::envelope`]
27//! override only when the adapter advertises
28//! [`Capabilities::custom_envelope`].
29//! - [`standard_message_headers`], render `Sender`, `Date`, and
30//! `Message-ID` as a `Vec<Header>` for adapters whose provider API treats
31//! them as custom headers.
32//!
33//! [`Message`]: email_message::Message
34
35pub mod options;
36pub mod string_newtype;
37#[cfg(feature = "tracing")]
38pub mod tracing;
39pub mod transport;
40
41pub use string_newtype::{STRING_NEWTYPE_MAX_BYTES, StringNewtypeError};
42#[cfg(feature = "tracing")]
43pub use tracing::TracingTransport;
44pub use transport::*;
45
46/// Re-export of [`email_message`] so leaf consumers can reach the typed
47/// outbound message and address model through a single dependency on
48/// `email-transport`. Provided as a facade, the `email-message` crate
49/// remains separately publishable and consumable.
50pub use email_message;
51
52/// Re-export of the `serde` crate so the [`string_newtype!`] macro can
53/// reach into serde's traits via `$crate::__macro_serde::*` instead of
54/// the bare `::serde` path when the `serde` feature is enabled. Downstream
55/// users who invoke [`string_newtype!`] therefore do **not** need to declare
56/// `serde` as a direct dependency themselves; it flows through
57/// `email-transport`'s re-export.
58///
59/// Not part of the curated rustdoc surface; do not name directly.
60#[cfg(feature = "serde")]
61#[doc(hidden)]
62pub use serde as __macro_serde;
63
64/// Re-export of the `schemars` crate so the [`string_newtype!`] macro can
65/// generate [`schemars::JsonSchema`] impls without requiring downstream macro
66/// users to declare `schemars` as a direct dependency.
67///
68/// Not part of the curated rustdoc surface; do not name directly.
69#[cfg(feature = "schemars")]
70#[doc(hidden)]
71pub use schemars as __macro_schemars;