imap_next/
lib.rs

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