mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
async-imap does not do its own buffering, but calls flush() after sending each command. Using BufWriter reduces the number of write() system calls used to send a single command. Note that BufWriter is set up on top of TLS streams, because we can't guarantee that TLS libraries flush the stream before waiting for response.
107 lines
2.7 KiB
Rust
107 lines
2.7 KiB
Rust
use std::ops::{Deref, DerefMut};
|
|
use std::pin::Pin;
|
|
use std::time::Duration;
|
|
|
|
use async_imap::types::Mailbox;
|
|
use async_imap::Session as ImapSession;
|
|
use async_native_tls::TlsStream;
|
|
use fast_socks5::client::Socks5Stream;
|
|
use tokio::io::BufWriter;
|
|
use tokio::net::TcpStream;
|
|
use tokio_io_timeout::TimeoutStream;
|
|
|
|
use super::capabilities::Capabilities;
|
|
|
|
#[derive(Debug)]
|
|
pub(crate) struct Session {
|
|
pub(super) inner: ImapSession<Box<dyn SessionStream>>,
|
|
|
|
pub capabilities: Capabilities,
|
|
|
|
/// Selected folder name.
|
|
pub selected_folder: Option<String>,
|
|
|
|
/// Mailbox structure returned by IMAP server.
|
|
pub selected_mailbox: Option<Mailbox>,
|
|
|
|
pub selected_folder_needs_expunge: bool,
|
|
}
|
|
|
|
pub(crate) trait SessionStream:
|
|
tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + Sync + std::fmt::Debug
|
|
{
|
|
/// Change the read timeout on the session stream.
|
|
fn set_read_timeout(&mut self, timeout: Option<Duration>);
|
|
}
|
|
|
|
impl SessionStream for Box<dyn SessionStream> {
|
|
fn set_read_timeout(&mut self, timeout: Option<Duration>) {
|
|
self.as_mut().set_read_timeout(timeout);
|
|
}
|
|
}
|
|
impl<T: SessionStream> SessionStream for TlsStream<T> {
|
|
fn set_read_timeout(&mut self, timeout: Option<Duration>) {
|
|
self.get_mut().set_read_timeout(timeout);
|
|
}
|
|
}
|
|
impl<T: SessionStream> SessionStream for BufWriter<T> {
|
|
fn set_read_timeout(&mut self, timeout: Option<Duration>) {
|
|
self.get_mut().set_read_timeout(timeout);
|
|
}
|
|
}
|
|
impl SessionStream for Pin<Box<TimeoutStream<TcpStream>>> {
|
|
fn set_read_timeout(&mut self, timeout: Option<Duration>) {
|
|
self.as_mut().set_read_timeout_pinned(timeout);
|
|
}
|
|
}
|
|
impl<T: SessionStream> SessionStream for Socks5Stream<T> {
|
|
fn set_read_timeout(&mut self, timeout: Option<Duration>) {
|
|
self.get_socket_mut().set_read_timeout(timeout)
|
|
}
|
|
}
|
|
|
|
impl Deref for Session {
|
|
type Target = ImapSession<Box<dyn SessionStream>>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.inner
|
|
}
|
|
}
|
|
|
|
impl DerefMut for Session {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.inner
|
|
}
|
|
}
|
|
|
|
impl Session {
|
|
pub(crate) fn new(
|
|
inner: ImapSession<Box<dyn SessionStream>>,
|
|
capabilities: Capabilities,
|
|
) -> Self {
|
|
Self {
|
|
inner,
|
|
capabilities,
|
|
selected_folder: None,
|
|
selected_mailbox: None,
|
|
selected_folder_needs_expunge: false,
|
|
}
|
|
}
|
|
|
|
pub fn can_idle(&self) -> bool {
|
|
self.capabilities.can_idle
|
|
}
|
|
|
|
pub fn can_move(&self) -> bool {
|
|
self.capabilities.can_move
|
|
}
|
|
|
|
pub fn can_check_quota(&self) -> bool {
|
|
self.capabilities.can_check_quota
|
|
}
|
|
|
|
pub fn can_condstore(&self) -> bool {
|
|
self.capabilities.can_condstore
|
|
}
|
|
}
|