Expand description
§io-smtp
I/O-free SMTP client coroutines: every network exchange is a resumable state machine emitting read and write requests instead of performing I/O itself, so the caller owns the socket and pumps the coroutine (see the client feature for a ready-made std-blocking pump).
§The coroutine contract
Every coroutine implements coroutine::SmtpCoroutine, whose
resume method takes an optional byte slice and yields a
coroutine::SmtpCoroutineState: either an intermediate
coroutine::SmtpYield asking the caller to read bytes from the
stream (fed back on the next resume, an empty slice signalling
EOF) or to write the yielded bytes, or a terminal value carrying
the result. Each module ships a runnable example of the pump loop,
and client::SmtpClientStd implements it once for blocking std
streams.
Most coroutines delegate their wire exchange to
send::SmtpCommandSend, the base coroutine owning the
serialise, write, read and parse cycle; they only interpret the
parsed reply code. The exceptions are the pure read coroutines
(the greeting and EHLO ones), which own their read loop because
nothing is written first, or because the multi-line reply needs
dedicated parsing.
§Layout: one folder per RFC
The source tree mirrors the SMTP specification landscape, one
module per RFC. rfc5321 hosts the SMTP core: the coroutines
for the greeting, the EHLO and HELO handshakes, the mail
transaction (MAIL FROM, RCPT TO, DATA with dot-stuffing), NOOP,
RSET, QUIT and a raw passthrough, next to the flattened
wire-format types (reply codes, responses, paths, domains,
parameters). The extensions follow: rfc1870 (message size
declaration), rfc3207 (STARTTLS), rfc3461 (delivery status
notifications), rfc3463 (enhanced status codes) and rfc4954
(the AUTH command and its continuation data).
Authentication mechanisms split in two. rfc7628 (OAUTHBEARER)
and rfc7677 (SCRAM-SHA-256, behind the scram feature) specify
cryptographic or transport behaviour beyond plain SASL framing, so
they live under their own RFC module. sasl hosts the
mechanisms with no such glue: PLAIN, LOGIN, ANONYMOUS and XOAUTH2.
Code spanning the RFC modules lives at the crate root:
coroutine defines the coroutine contract and the smtp_try
macro, send the base send-one-command coroutine, message
the composite whole-message send coroutine, the private utils module the shared
byte-escaping and parser helpers, and client the optional
std-blocking client (client feature) exposing one method per
coroutine plus, with a TLS feature enabled, an end-to-end connect
covering transport, STARTTLS and SASL.
§Conventions
The crate is unconditionally no_std; alloc is always required, std only under the client feature. Public items carry the bare Smtp domain prefix (SMTP is not versioned). Coroutine errors normalise to the shape “SMTP operation failed: cause”, and RFC wire tokens (mechanism names, capability keywords) keep their exact spelling.
Modules§
- client
client - Standard, blocking SMTP client
- coroutine
- Generator-shape coroutine contract. Mirrors
core::ops::Coroutine:Yieldfor intermediate progress,Returnfor terminal output,SmtpCoroutineStatefor both. - message
- SMTP composite coroutine; chains MAIL FROM, one RCPT TO per recipient, then DATA.
- rfc1870
- RFC 1870: SMTP Service Extension for Message Size Declaration.
- rfc3207
- RFC 3207: SMTP Service Extension for Secure SMTP over Transport Layer Security.
- rfc3461
- RFC 3461: Simple Mail Transfer Protocol (SMTP) Service Extension for Delivery Status Notifications (DSNs).
- rfc3463
- RFC 3463: Enhanced Mail System Status Codes.
- rfc4954
- RFC 4954: SMTP Service Extension for Authentication.
- rfc5321
- RFC 5321: Simple Mail Transfer Protocol.
- rfc7628
- RFC 7628: A Set of Simple Authentication and Security Layer (SASL) Mechanisms for OAuth.
- rfc7677
scram - RFC 7677: SCRAM-SHA-256 and SCRAM-SHA-256-PLUS SASL Mechanisms.
- sasl
- SASL mechanisms wrapped behind the SMTP AUTH verb (RFC 4954).
- send
- Base coroutine that every higher-level SMTP coroutine delegates
to: serialises a command, runs the read/write exchange, and feeds
the reply through
SmtpResponse::is_complete/SmtpResponse::parse.
Macros§
- smtp_
try - Coroutine
?: forwardsYielded(viaInto), short-circuits onErr, evaluates to the innerOkvalue.