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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! `daaki` IMAP client library.
//!
//! An `IMAP4rev1` (RFC 3501) and `IMAP4rev2` (RFC 9051) async client
//! built on tokio and rustls. Single crate — parser, types, and connection
//! in one place.
//!
//! # Architecture
//!
//! ## Driver task
//!
//! [`ImapConnection`] is a lightweight handle — it holds an
//! `mpsc::Sender<DriverCommand>` and a `watch::Receiver` for state
//! snapshots. A dedicated tokio task (the *driver*) owns the TCP/TLS
//! stream exclusively. All public methods take `&self`, submit commands
//! over the channel, and await a result via a `oneshot`. Dropping a
//! future mid-flight cannot corrupt the stream because no caller-side
//! future has access to it — the driver completes the in-flight command
//! and only the result is abandoned. This makes `tokio::select!` and
//! `tokio::time::timeout` safe to use around any operation.
//!
//! ## Consumer trait
//!
//! Each IMAP command is executed by a [`Consumer`](connection::dispatch)
//! implementation. The driver feeds the consumer pre-classified responses
//! via `on_response`, then calls `finalize` when the tagged response
//! arrives. Consumers never make routing decisions — they only accumulate
//! data they are given. Commands that expect `+` continuations (e.g.
//! AUTHENTICATE) use the separate `ContinuationConsumer` trait with an
//! additional `on_continuation` method.
//!
//! ## Classification truth table
//!
//! The function [`classify`](codec::classification::classify) is the
//! single source of truth for whether an untagged response belongs to
//! the current command's result or to the asynchronous event queue.
//! Every row cites the RFC section that defines the routing rule.
//! The dispatcher calls `classify` before each response and routes
//! mechanically — consumers have no routing decision to make.
//!
//! ## Typed event queue
//!
//! Asynchronous server notifications — ALERTs, EXISTS/EXPUNGE changes,
//! NOTIFY data, BYE — arrive as [`TypedEvent`]s. Poll them with
//! [`drain_events`](ImapConnection::drain_events) (non-blocking) or
//! [`next_event`](ImapConnection::next_event) (with timeout). The
//! driver publishes events via a non-blocking `DriverEventSink` that
//! can never suspend the driver's select loop.
//!
//! ## Wire reader and protocol state
//!
//! All wire reads flow through a private `WireReader` in `mod wire`,
//! which is visible only within the `connection` module. All protocol
//! state mutations flow through
//! `ProtocolState::apply_side_effects` in `mod state` — the primary
//! mutator. The state module's fields are `pub(self)`, so direct
//! field assignment from outside `mod state` is a compile error.
//!
//! ## `MailboxName`
//!
//! Every mailbox name in every public type is [`MailboxName`] — a
//! validated, decoded UTF-8 newtype with no `From<String>` impl. The
//! only constructors are `new` (public, validating) and `from_decoded`
//! (`pub(crate)`, for already-parsed wire data in the codec). The
//! compiler refuses to smuggle wire-form bytes through any public type.
// `fuzzing` cfg is set by cargo-fuzz (nightly) — not known to check-cfg.
pub use ;
/// Re-export the canonical `Address` type from `daaki-message` so consumers
/// can use a single `Address` type across the IMAP, SMTP, and message crates
/// without manual field-by-field conversion.
pub use Address;
pub use Error;
pub use ;
/// Result type alias for IMAP operations.
pub type Result<T> = Result;
/// Fuzz-only entry points. Not part of the public API.
///
/// Exposed behind `#[cfg(fuzzing)]` (set automatically by `cargo-fuzz`) so
/// that out-of-crate fuzz harnesses can reach the `pub(crate)` codec parsers.
/// Consumer-facing README examples must compile against the current public API.
///
/// This turns the README into executable doctests so stale helper signatures
/// and example code are caught during `cargo test --doc`.