Skip to main content

wasm_smtp/
lib.rs

1//! # wasm-smtp
2//!
3//! Environment-independent SMTP client core for WASM and other constrained
4//! runtimes.
5//!
6//! This crate implements the SMTP state machine, response parsing, command
7//! formatting, dot-stuffing, and error classification. It is intentionally
8//! free of any runtime-specific socket code: applications must provide a
9//! [`Transport`] implementation that wraps the runtime-native socket type.
10//! Adapter crates such as `wasm-smtp-cloudflare` provide ready-made
11//! transports.
12//!
13//! ## Scope
14//!
15//! - **TLS is required.** Implicit TLS (port 465) is the standard connection
16//!   model. STARTTLS (port 587) is also supported via
17//!   [`SmtpClient::connect_starttls`] and the [`StartTlsCapable`] trait; see
18//!   those pages for usage. In both cases the TLS handshake itself is the
19//!   [`Transport`] implementation's responsibility — the core operates on an
20//!   already-secure byte stream.
21//! - **MIME composition is out of scope.** Callers pass a fully-formed,
22//!   CRLF-normalized message body string to [`SmtpClient::send_mail`].
23//! - **Bulk delivery, retry queues, and rate limiting are out of scope.** They
24//!   belong in the calling application.
25//!
26//! ## Example
27//!
28//! ```ignore
29//! use wasm_smtp::{SmtpClient, Transport};
30//!
31//! async fn send<T: Transport>(transport: T) -> Result<(), wasm_smtp::SmtpError> {
32//!     let mut client = SmtpClient::connect(transport, "client.example.com").await?;
33//!     // login() picks the best mechanism the server advertised:
34//!     // PLAIN if available, falling back to LOGIN. For explicit
35//!     // control, use login_with(AuthMechanism::Plain, …).
36//!     client.login("user@example.com", "secret").await?;
37//!     client.send_mail(
38//!         "user@example.com",
39//!         &["recipient@example.org"],
40//!         "From: user@example.com\r\n\
41//!          To: recipient@example.org\r\n\
42//!          Subject: Hello\r\n\
43//!          \r\n\
44//!          Body text.\r\n",
45//!     ).await?;
46//!     client.quit().await?;
47//!     Ok(())
48//! }
49//! ```
50//!
51//! ## Acceptable use
52//!
53//! See `TERMS_OF_USE.md` at the repository root. This crate must not be used
54//! to deliver unsolicited bulk mail, to impersonate other senders, or to
55//! deliver mail that violates the operating policy of any SMTP server.
56
57pub mod audit;
58pub mod client;
59pub mod error;
60pub mod message_body;
61pub mod outcome;
62pub mod policy;
63pub mod protocol;
64pub mod session;
65pub mod transport;
66
67#[cfg(feature = "scram-sha-256")]
68mod scram;
69
70mod tracing_helpers;
71
72pub use client::{SmtpClient, SmtpClientOptions};
73pub use error::{AuthError, InvalidInputError, IoError, PolicyError, ProtocolError, SmtpError, SmtpOp};
74pub use message_body::MessageBody;
75pub use outcome::SendOutcome;
76pub use protocol::{AuthMechanism, DotStufferState, EnhancedStatus};
77pub use session::SessionState;
78pub use transport::{StartTlsCapable, Transport};
79
80#[cfg(test)]
81mod tests;