Skip to main content

imap_client/
lib.rs

1//! Async, type-state IMAP client for the
2//! [`imap-rs`](https://crates.io/crates/imap-rs) library.
3//!
4//! This crate owns the session state machine and the command dispatcher. It is
5//! transport-agnostic: drive it with any `AsyncRead + AsyncWrite` stream (see
6//! [`imap-rs-tls`](https://crates.io/crates/imap-rs-tls) for a ready-made
7//! `rustls` transport).
8//!
9//! # Highlights
10//!
11//! - [`Session`] is type-stated over protocol phase ([`Unauthenticated`],
12//!   [`Authenticated`], [`Selected`]) and transport ([`PlainText`], [`Tls`]),
13//!   so invalid command sequences fail to compile.
14//! - [`RawClient`] is the lower-level pipelining dispatcher: it routes tagged
15//!   responses back to callers and broadcasts untagged events.
16//! - Credentials ([`credentials::Password`], [`credentials::OAuthToken`]) are
17//!   zeroized on drop and redacted in `Debug`.
18#![forbid(unsafe_code)]
19
20pub mod capabilities;
21pub mod client;
22pub mod credentials;
23pub mod error;
24pub mod flags;
25pub mod idle;
26pub mod search;
27pub mod session;
28
29pub use capabilities::Capabilities;
30pub use client::RawClient;
31pub use error::ClientError;
32pub use flags::{Flag, StoreAction};
33pub use search::{SearchKey, SearchQuery};
34pub use session::{Authenticated, PlainText, Selected, Session, Tls, Unauthenticated};
35
36#[cfg(test)]
37mod tests {
38
39    #[test]
40    fn test_type_states() {
41        // This test ensures that the generic state machine builds and provides the expected interface.
42        // We cannot call .fetch() on an Unauthenticated session, and we cannot call login() on a PlainText session!
43
44        // let raw = RawClient::new(mock_stream);
45        // let unauth = Session::<Unauthenticated, Tls>::new(raw, Capabilities::default());
46        // let auth = unauth.login("user", credentials::Password::new("pass")).await.unwrap();
47    }
48}