mailrs_smtp_proto/lib.rs
1#![deny(missing_docs)]
2#![deny(rustdoc::broken_intra_doc_links)]
3
4//! SMTP protocol parser, formatter, and session state machine.
5//!
6//! `mailrs-smtp-proto` is a zero-I/O implementation of [RFC 5321] (SMTP) and
7//! its common extensions: STARTTLS ([RFC 3207]), AUTH PLAIN / LOGIN
8//! ([RFC 4954]), and SMTPUTF8 ([RFC 6531]). It parses incoming command lines
9//! into typed `Command` enums, formats outgoing responses, and drives the
10//! SMTP session state machine — but it never touches the network. The caller
11//! owns all I/O.
12//!
13//! This crate underpins the inbound SMTP server in [mailrs], a Rust mail
14//! server, and is published independently so other Rust projects can reuse
15//! the parsing + state-machine layer without pulling in a full server.
16//!
17//! # Quick start
18//!
19//! ```
20//! use mailrs_smtp_proto::{parse_command, Command, Session, SessionConfig, Event};
21//!
22//! // parse a wire-format command line
23//! let cmd = parse_command("EHLO mail.example.com").unwrap();
24//! assert!(matches!(cmd, Command::Ehlo("mail.example.com")));
25//!
26//! // drive the session state machine
27//! let mut session = Session::new("smtp.example.com", SessionConfig::default());
28//! let event = session.handle_command(&cmd);
29//! assert!(matches!(event, Event::Reply(_)));
30//! ```
31//!
32//! # What this crate does
33//!
34//! - **Parsing**: [`parse_command`] turns a wire-format command line into a
35//! borrowed [`Command<'_>`] enum (zero-copy).
36//! - **Formatting**: [`Response`] and its constructors produce wire-format
37//! reply lines; [`format_ehlo_response`] handles multi-line EHLO.
38//! - **State machine**: [`Session`] tracks the SMTP transaction state and
39//! maps `Command` → [`Event`] decisions (reply / open DATA / start TLS /
40//! authenticate / shut down).
41//! - **DATA helpers**: [`unstuff_line`] / [`unstuff_data`] handle the
42//! dot-stuffing convention used in the DATA stage.
43//! - **SASL**: [`auth::decode_plain`] / [`auth::decode_login_response`]
44//! decode AUTH PLAIN / LOGIN payloads.
45//!
46//! # What this crate does NOT do
47//!
48//! - No I/O. No TCP, no TLS, no async runtime. The caller wires it.
49//! - No content scanning, no message storage, no DKIM/SPF/DMARC.
50//! - No outbound SMTP client. See `mailrs-smtp-client` for that.
51//!
52//! [RFC 5321]: https://datatracker.ietf.org/doc/html/rfc5321
53//! [RFC 3207]: https://datatracker.ietf.org/doc/html/rfc3207
54//! [RFC 4954]: https://datatracker.ietf.org/doc/html/rfc4954
55//! [RFC 6531]: https://datatracker.ietf.org/doc/html/rfc6531
56//! [mailrs]: https://github.com/goliajp/mailrs
57
58pub mod address;
59pub mod auth;
60pub mod command;
61pub mod data;
62pub mod parse;
63pub mod response;
64pub mod session;
65
66pub use command::{AuthMechanism, Command, ForwardPath, Param, ReversePath};
67pub use data::{unstuff_data, unstuff_line};
68pub use parse::{ParseError, parse_command};
69pub use response::{EnhancedCode, Response, format_ehlo_response};
70pub use session::{AuthStep, Event, MAX_MESSAGE_SIZE, MAX_RECIPIENTS, Session, SessionConfig, State};