1 parent
cfc74d9db6
commit
dacdf9c27d
76 files changed
+5209
-741
No files matched your search
+91
-15
@@ -19,6 +19,60 @@ pub(crate) use super::connection::connect;
|
||||
#[path = "mock.rs"]
|
||||
pub mod mock;
|
||||
|
||||
async fn folder_status_extended_on_session(
|
||||
session: &mut async_imap::Session<super::connection::ImapStream>,
|
||||
folder: &str,
|
||||
) -> Result<FolderStatusExtended, ImapError> {
|
||||
if let Ok(mailbox) = session
|
||||
.status(
|
||||
folder,
|
||||
"(MESSAGES UIDNEXT UIDVALIDITY UNSEEN HIGHESTMODSEQ)",
|
||||
)
|
||||
.await
|
||||
&& let Some(unseen) = mailbox.unseen
|
||||
{
|
||||
return Ok(FolderStatusExtended {
|
||||
uid_validity: mailbox.uid_validity.unwrap_or(0),
|
||||
exists: mailbox.exists,
|
||||
uid_next: mailbox.uid_next.unwrap_or(0),
|
||||
unseen,
|
||||
highest_modseq: mailbox.highest_modseq.unwrap_or(0),
|
||||
});
|
||||
}
|
||||
|
||||
if let Ok(mailbox) = session
|
||||
.status(folder, "(MESSAGES UIDNEXT UIDVALIDITY UNSEEN)")
|
||||
.await
|
||||
&& let Some(unseen) = mailbox.unseen
|
||||
{
|
||||
return Ok(FolderStatusExtended {
|
||||
uid_validity: mailbox.uid_validity.unwrap_or(0),
|
||||
exists: mailbox.exists,
|
||||
uid_next: mailbox.uid_next.unwrap_or(0),
|
||||
unseen,
|
||||
highest_modseq: mailbox.highest_modseq.unwrap_or(0),
|
||||
});
|
||||
}
|
||||
|
||||
let mailbox = match session.select_condstore(folder).await {
|
||||
Ok(mailbox) => mailbox,
|
||||
Err(_) => session.select(folder).await.map_err(map_imap_error)?,
|
||||
};
|
||||
let unseen = session
|
||||
.uid_search("UNSEEN")
|
||||
.await
|
||||
.map_err(map_imap_error)?
|
||||
.len() as u32;
|
||||
|
||||
Ok(FolderStatusExtended {
|
||||
uid_validity: mailbox.uid_validity.unwrap_or(0),
|
||||
exists: mailbox.exists,
|
||||
uid_next: mailbox.uid_next.unwrap_or(0),
|
||||
unseen,
|
||||
highest_modseq: mailbox.highest_modseq.unwrap_or(0),
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[allow(clippy::double_must_use)]
|
||||
#[async_trait]
|
||||
@@ -170,6 +224,21 @@ pub trait ImapClient: Send + Sync {
|
||||
folder: &str,
|
||||
) -> Result<FolderStatusExtended, ImapError>;
|
||||
|
||||
async fn folder_statuses_extended(
|
||||
&self,
|
||||
creds: &ImapCredentials,
|
||||
folders: &[String],
|
||||
) -> Result<Vec<(String, FolderStatusExtended)>, ImapError> {
|
||||
let mut statuses = Vec::with_capacity(folders.len());
|
||||
for folder in folders {
|
||||
statuses.push((
|
||||
folder.clone(),
|
||||
self.folder_status_extended(creds, folder).await?,
|
||||
));
|
||||
}
|
||||
Ok(statuses)
|
||||
}
|
||||
|
||||
async fn fetch_changed_flags(
|
||||
&self,
|
||||
creds: &ImapCredentials,
|
||||
@@ -1073,25 +1142,32 @@ impl ImapClient for RealImapClient {
|
||||
folder: &str,
|
||||
) -> Result<FolderStatusExtended, ImapError> {
|
||||
let mut session = self.pool.checkout(creds).await?;
|
||||
let result = folder_status_extended_on_session(&mut session, folder).await;
|
||||
if result.is_ok() {
|
||||
session.recycle();
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
let mailbox = session
|
||||
.status(
|
||||
folder,
|
||||
"(MESSAGES UIDNEXT UIDVALIDITY UNSEEN HIGHESTMODSEQ)",
|
||||
)
|
||||
.await
|
||||
.map_err(map_imap_error)?;
|
||||
async fn folder_statuses_extended(
|
||||
&self,
|
||||
creds: &ImapCredentials,
|
||||
folders: &[String],
|
||||
) -> Result<Vec<(String, FolderStatusExtended)>, ImapError> {
|
||||
let mut session = self.pool.checkout(creds).await?;
|
||||
let mut statuses = Vec::with_capacity(folders.len());
|
||||
|
||||
let result = FolderStatusExtended {
|
||||
uid_validity: mailbox.uid_validity.unwrap_or(0),
|
||||
exists: mailbox.exists,
|
||||
uid_next: mailbox.uid_next.unwrap_or(0),
|
||||
unseen: mailbox.unseen.unwrap_or(0),
|
||||
highest_modseq: mailbox.highest_modseq.unwrap_or(0),
|
||||
};
|
||||
for folder in folders {
|
||||
match folder_status_extended_on_session(&mut session, folder).await {
|
||||
Ok(status) => statuses.push((folder.clone(), status)),
|
||||
Err(error) => {
|
||||
tracing::debug!(folder = %folder, error = %error, "Skipping folder STATUS refresh");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
session.recycle();
|
||||
Ok(result)
|
||||
Ok(statuses)
|
||||
}
|
||||
|
||||
async fn fetch_changed_flags(
|
||||
|
||||
Reference in new issue
Block a user