imap_next/lib.rs
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
#![forbid(unsafe_code)]
pub mod client;
mod client_send;
mod handle;
mod receive;
pub mod server;
mod server_send;
#[cfg(feature = "stream")]
pub mod stream;
#[cfg(test)]
mod tests;
pub mod types;
// Re-export(s)
pub use imap_codec::imap_types;
// Test examples from imap-next's README.
#[doc = include_str!("../README.md")]
#[cfg(doctest)]
pub struct ReadmeDoctests;
/// State machine with sans I/O pattern.
///
/// This trait is the interface between types that implement IMAP protocol flows and I/O drivers.
/// Most notably [`Client`](client::Client) and [`Server`](server::Server) both implement
/// this trait whereas [`Stream`](stream::Stream) uses the trait for implementing the I/O drivers.
pub trait State {
/// Event emitted while progressing the state.
type Event;
/// Error emitted while progressing the state.
type Error;
/// Enqueue input bytes.
///
/// These bytes may be used during the next [`Self::next`] call.
fn enqueue_input(&mut self, bytes: &[u8]);
/// Progress the state until the next event (or interrupt).
fn next(&mut self) -> Result<Self::Event, Interrupt<Self::Error>>;
}
impl<F: State> State for &mut F {
type Event = F::Event;
type Error = F::Error;
fn enqueue_input(&mut self, bytes: &[u8]) {
(*self).enqueue_input(bytes);
}
fn next(&mut self) -> Result<Self::Event, Interrupt<Self::Error>> {
(*self).next()
}
}
/// State progression was interrupted by an event that needs to be handled externally.
#[must_use = "If state progression is interrupted the interrupt must be handled. Ignoring this might result in a deadlock on IMAP level"]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Interrupt<E> {
/// An IO operation is necessary. Ignoring this might result in a deadlock on IMAP level.
Io(Io),
/// An error occurred. Ignoring this might result in an undefined IMAP state.
Error(E),
}
/// User of `imap-next` must perform an IO operation to progress the state.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Io {
/// More bytes must be read and passed to [`State::enqueue_input`].
NeedMoreInput,
/// Given bytes must be written.
Output(Vec<u8>),
}