imap_next/lib.rs
1#![forbid(unsafe_code)]
2
3pub mod client;
4mod client_send;
5mod handle;
6mod receive;
7pub mod server;
8mod server_send;
9#[cfg(feature = "stream")]
10pub mod stream;
11#[cfg(test)]
12mod tests;
13pub mod types;
14
15// Re-export(s)
16pub use imap_codec::imap_types;
17
18// Test examples from imap-next's README.
19#[doc = include_str!("../README.md")]
20#[cfg(doctest)]
21pub struct ReadmeDoctests;
22
23/// State machine with sans I/O pattern.
24///
25/// This trait is the interface between types that implement IMAP protocol flows and I/O drivers.
26/// Most notably [`Client`](client::Client) and [`Server`](server::Server) both implement
27/// this trait whereas [`Stream`](stream::Stream) uses the trait for implementing the I/O drivers.
28pub trait State {
29 /// Event emitted while progressing the state.
30 type Event;
31
32 /// Error emitted while progressing the state.
33 type Error;
34
35 /// Enqueue input bytes.
36 ///
37 /// These bytes may be used during the next [`Self::next`] call.
38 fn enqueue_input(&mut self, bytes: &[u8]);
39
40 /// Progress the state until the next event (or interrupt).
41 fn next(&mut self) -> Result<Self::Event, Interrupt<Self::Error>>;
42}
43
44impl<F: State> State for &mut F {
45 type Event = F::Event;
46 type Error = F::Error;
47
48 fn enqueue_input(&mut self, bytes: &[u8]) {
49 (*self).enqueue_input(bytes);
50 }
51
52 fn next(&mut self) -> Result<Self::Event, Interrupt<Self::Error>> {
53 (*self).next()
54 }
55}
56
57/// State progression was interrupted by an event that needs to be handled externally.
58#[must_use = "If state progression is interrupted the interrupt must be handled. Ignoring this might result in a deadlock on IMAP level"]
59#[derive(Clone, Debug, Eq, PartialEq)]
60pub enum Interrupt<E> {
61 /// An IO operation is necessary. Ignoring this might result in a deadlock on IMAP level.
62 Io(Io),
63 /// An error occurred. Ignoring this might result in an undefined IMAP state.
64 Error(E),
65}
66
67/// User of `imap-next` must perform an IO operation to progress the state.
68#[derive(Clone, Debug, Eq, PartialEq)]
69pub enum Io {
70 /// More bytes must be read and passed to [`State::enqueue_input`].
71 NeedMoreInput,
72 /// Given bytes must be written.
73 Output(Vec<u8>),
74}