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}