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}