Clean up use of generics on Session

This commit is contained in:
Nick Krichevsky 2022-05-12 18:38:08 -04:00
parent 4409abd1fa
commit 6d3505a960
4 changed files with 25 additions and 36 deletions

View file

@ -1,27 +1,18 @@
use std::error::Error;
use std::{fmt::Debug, time::Duration};
use async_imap::{
extensions::idle::{Handle, IdleResponse},
imap_proto::{MailboxDatum, Response},
Session,
};
use futures::{AsyncRead, AsyncWrite, StreamExt};
use crate::inbox::SequenceNumber;
use crate::IMAPSession;
use futures::StreamExt;
/// `fetch_email` will consume the current session and put it into an `Idle` state, until a new email is received
///
/// # Errors
/// If, for any reason, the email fails to be fetched, one of `async_imap` error's will be returned.
#[allow(clippy::module_name_repetitions)]
pub async fn fetch_email<T>(
session: &mut Session<T>,
pub async fn fetch_email(
session: &mut IMAPSession,
sequence_number: SequenceNumber,
) -> Result<String, Box<dyn Error>>
where
T: AsyncRead + AsyncWrite + Unpin + Debug + Send,
{
) -> Result<String, Box<dyn Error>> {
let message = session
.fetch(format!("{}", sequence_number.value()), "RFC822")
.await?

View file

@ -4,12 +4,13 @@ use async_imap::{
error::{Error as IMAPError, Result as IMAPResult},
extensions::idle::Handle,
imap_proto::{MailboxDatum, Response},
Session,
};
use futures::{AsyncRead, AsyncWrite};
use thiserror::Error;
use tokio::sync::broadcast::{self, error::SendError};
use crate::{IMAPClient, IMAPSession, IMAPTransportStream};
mod idle;
#[derive(Clone, Copy, Debug)]
@ -58,10 +59,7 @@ impl Watcher {
/// Watch for the arrival of a single email. While the `Watcher` is watching, the caller must relinquish ownership
/// of the `Session`, but it will be returned to it upon succesful completion of the
pub async fn watch_for_email<T>(&self, session: Session<T>) -> Result<Session<T>, WatchError>
where
T: AsyncRead + AsyncWrite + Unpin + Debug + Send,
{
pub async fn watch_for_email(&self, session: IMAPSession) -> Result<IMAPSession, WatchError> {
let mut idle_handle = session.idle();
let sequence_number = Self::idle_for_email(&mut idle_handle).await?;
self.sender.send(sequence_number)?;
@ -70,10 +68,9 @@ impl Watcher {
Ok(reclaimed_session)
}
async fn idle_for_email<T>(idle_handle: &mut Handle<T>) -> IMAPResult<SequenceNumber>
where
T: AsyncRead + AsyncWrite + Unpin + Debug + Send,
{
async fn idle_for_email(
idle_handle: &mut Handle<IMAPTransportStream>,
) -> IMAPResult<SequenceNumber> {
loop {
idle_handle.init().await?;
let idle_res = idle::wait_for_data(idle_handle).await;

View file

@ -2,12 +2,14 @@ use std::{fmt::Debug, time::Duration};
use thiserror::Error;
use async_imap::{
error::{Error as IMAPError, Result as IMAPResult},
error::Error as IMAPError,
extensions::idle::{Handle, IdleResponse},
imap_proto::Response as IMAPResponse,
};
use futures::{AsyncRead, AsyncWrite};
use crate::IMAPTransportStream;
// 29 minutes, as per RFC2177 which specifies we should re-issue our idle every 29 minutes
const WAIT_TIMEOUT: Duration = Duration::from_secs(29 * 60);
@ -55,10 +57,7 @@ impl Data {
}
}
pub async fn wait_for_data<T>(idle_handle: &mut Handle<T>) -> Result<Data, Error>
where
T: AsyncRead + AsyncWrite + Unpin + Debug + Send,
{
pub async fn wait_for_data(idle_handle: &mut Handle<IMAPTransportStream>) -> Result<Data, Error> {
println!("starting timeout wait...");
let (idle_response_future, _stop) = idle_handle.wait_with_timeout(WAIT_TIMEOUT);
let idle_response = idle_response_future.await?;

View file

@ -7,8 +7,9 @@ extern crate log;
use std::fmt::Debug;
use async_imap::{self, Client, Session};
use async_native_tls::TlsConnector;
use async_imap;
use async_native_tls::{TlsConnector, TlsStream};
use async_std::net::TcpStream;
pub use config::{Config, IMAP as IMAPConfig};
use futures::{AsyncRead, AsyncWrite};
@ -20,9 +21,12 @@ mod inbox;
pub use fetch::fetch_email;
pub use inbox::{SequenceNumber, Watcher};
pub async fn setup_session(
cfg: &Config,
) -> async_imap::error::Result<Session<impl AsyncRead + AsyncWrite + Unpin + Debug + Send>> {
type IMAPTransportStream = TlsStream<TcpStream>;
// TODO: Probably doesn't need to be pub
type IMAPClient = async_imap::Client<IMAPTransportStream>;
pub type IMAPSession = async_imap::Session<IMAPTransportStream>;
pub async fn setup_session(cfg: &Config) -> async_imap::error::Result<IMAPSession> {
let imap_cfg = cfg.imap();
println!("Logging in...");
let client = build_imap_client(imap_cfg).await?;
@ -33,9 +37,7 @@ pub async fn setup_session(
.map_err(|err| err.0)
}
async fn build_imap_client(
imap_cfg: &IMAPConfig,
) -> async_imap::error::Result<Client<impl AsyncRead + AsyncWrite + Unpin + Debug>> {
async fn build_imap_client(imap_cfg: &IMAPConfig) -> async_imap::error::Result<IMAPClient> {
let tls_connector = TlsConnector::new();
async_imap::connect(
(imap_cfg.domain(), imap_cfg.port()),