Skip to main content

wasm_smtp_cloudflare/
lib.rs

1//! # wasm-smtp-cloudflare
2//!
3//! Cloudflare Workers socket adapter for [`wasm-smtp`].
4//!
5//! This crate is a thin bridge between the Cloudflare Workers runtime's
6//! TCP socket API (`worker::Socket`) and the
7//! [`wasm-smtp::Transport`] / [`wasm-smtp::StartTlsCapable`]
8//! contracts. It does not implement SMTP itself; everything
9//! protocol-shaped lives in `wasm-smtp`.
10//!
11//! ## Scope
12//!
13//! - Open a TCP connection from a Worker using `worker::connect()`.
14//! - Configure either Implicit TLS (`SecureTransport::On`, port 465)
15//!   or STARTTLS (`SecureTransport::StartTls`, port 587).
16//! - Wrap the resulting `worker::Socket` so it implements both
17//!   `wasm-smtp::Transport` and (for STARTTLS)
18//!   `wasm-smtp::StartTlsCapable`.
19//! - Translate Workers-side I/O failures into
20//!   [`wasm-smtp::IoError`] strings.
21//!
22//! ## Out of scope
23//!
24//! - SMTP state, command formatting, response parsing, dot-stuffing —
25//!   these belong in `wasm-smtp`.
26//! - MIME composition or attachment building — supply a fully-formed
27//!   RFC 5322 message as the body.
28//!
29//! ## Quick start (Implicit TLS, port 465)
30//!
31//! ```ignore
32//! use wasm_smtp_cloudflare::connect_smtps;
33//!
34//! # async fn handler() -> Result<(), wasm_smtp::SmtpError> {
35//! let mut client = connect_smtps("smtp.example.com", 465, "client.example.com").await?;
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//! ## Quick start (STARTTLS, port 587)
52//!
53//! ```ignore
54//! use wasm_smtp_cloudflare::connect_smtp_starttls;
55//!
56//! # async fn handler() -> Result<(), wasm_smtp::SmtpError> {
57//! let mut client =
58//!     connect_smtp_starttls("smtp.example.com", 587, "client.example.com").await?;
59//! client.login("user@example.com", "secret").await?;
60//! // ... same as above
61//! # Ok(())
62//! # }
63//! ```
64//!
65//! ## Targets
66//!
67//! Production code only runs on `wasm32-unknown-unknown` inside the
68//! Cloudflare Workers runtime. The crate compiles on host targets so
69//! that `cargo check` can validate types and so that the conversion
70//! helpers in [`adapter`] can be unit-tested against `tokio-test` mocks
71//! — but at runtime, `worker::Socket` requires the Workers runtime.
72//!
73//! [`wasm-smtp`]: https://docs.rs/wasm-smtp
74//! [`wasm-smtp::Transport`]: https://docs.rs/wasm-smtp/latest/wasm_smtp/trait.Transport.html
75//! [`wasm-smtp::StartTlsCapable`]: https://docs.rs/wasm-smtp/latest/wasm_smtp/trait.StartTlsCapable.html
76//! [`wasm-smtp::IoError`]: https://docs.rs/wasm-smtp/latest/wasm_smtp/struct.IoError.html
77
78pub mod adapter;
79pub mod integration;
80pub mod socket;
81
82pub use adapter::CloudflareTransport;
83pub use integration::{connect_smtp_starttls, connect_smtps};
84pub use socket::{connect_implicit_tls, connect_starttls};
85
86/// Re-export of the core `Transport` trait so that callers depending on
87/// this crate do not need a direct dependency on `wasm-smtp` for
88/// the most common use.
89pub use wasm_smtp::Transport;
90
91/// Re-export of `StartTlsCapable` for callers that want to call
92/// `upgrade_to_tls` directly.
93pub use wasm_smtp::StartTlsCapable;
94
95/// Re-export of `SmtpClient` for convenience: `connect_smtps` returns
96/// `SmtpClient<CloudflareTransport>`.
97pub use wasm_smtp::SmtpClient;
98
99/// Re-export of `SmtpError` for convenience.
100pub use wasm_smtp::SmtpError;
101
102#[cfg(test)]
103mod tests;