1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! # 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.
extern crate alloc;
extern crate std;
pub