mirror of
https://github.com/chatmail/core.git
synced 2026-04-29 11:26:29 +03:00
Move select_folder to a separate submodule
This commit is contained in:
committed by
holger krekel
parent
b274482125
commit
49b9b28c99
@@ -28,6 +28,8 @@ use crate::param::Params;
|
|||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
use crate::wrapmime;
|
use crate::wrapmime;
|
||||||
|
|
||||||
|
pub mod select_folder;
|
||||||
|
|
||||||
const DC_IMAP_SEEN: usize = 0x0001;
|
const DC_IMAP_SEEN: usize = 0x0001;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
@@ -460,92 +462,6 @@ impl Imap {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// select a folder, possibly update uid_validity and, if needed,
|
|
||||||
/// expunge the folder to remove delete-marked messages.
|
|
||||||
async fn select_folder<S: AsRef<str>>(
|
|
||||||
&self,
|
|
||||||
context: &Context,
|
|
||||||
folder: Option<S>,
|
|
||||||
) -> Result<()> {
|
|
||||||
if self.session.lock().await.is_none() {
|
|
||||||
let mut cfg = self.config.write().await;
|
|
||||||
cfg.selected_folder = None;
|
|
||||||
cfg.selected_folder_needs_expunge = false;
|
|
||||||
return Err(Error::NoSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there is a new folder and the new folder is equal to the selected one, there's nothing to do.
|
|
||||||
// if there is _no_ new folder, we continue as we might want to expunge below.
|
|
||||||
if let Some(ref folder) = folder {
|
|
||||||
if let Some(ref selected_folder) = self.config.read().await.selected_folder {
|
|
||||||
if folder.as_ref() == selected_folder {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then)
|
|
||||||
let needs_expunge = { self.config.read().await.selected_folder_needs_expunge };
|
|
||||||
if needs_expunge {
|
|
||||||
if let Some(ref folder) = self.config.read().await.selected_folder {
|
|
||||||
info!(context, "Expunge messages in \"{}\".", folder);
|
|
||||||
|
|
||||||
// A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see
|
|
||||||
// https://tools.ietf.org/html/rfc3501#section-6.4.2
|
|
||||||
if let Some(ref mut session) = &mut *self.session.lock().await {
|
|
||||||
match session.close().await {
|
|
||||||
Ok(_) => {
|
|
||||||
info!(context, "close/expunge succeeded");
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
return Err(Error::CloseExpungeFailed(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err(Error::NoSession);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.config.write().await.selected_folder_needs_expunge = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// select new folder
|
|
||||||
if let Some(ref folder) = folder {
|
|
||||||
if let Some(ref mut session) = &mut *self.session.lock().await {
|
|
||||||
let res = session.select(folder).await;
|
|
||||||
|
|
||||||
// https://tools.ietf.org/html/rfc3501#section-6.3.1
|
|
||||||
// says that if the server reports select failure we are in
|
|
||||||
// authenticated (not-select) state.
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Ok(mailbox) => {
|
|
||||||
let mut config = self.config.write().await;
|
|
||||||
config.selected_folder = Some(folder.as_ref().to_string());
|
|
||||||
config.selected_mailbox = Some(mailbox);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(async_imap::error::Error::ConnectionLost) => {
|
|
||||||
self.trigger_reconnect();
|
|
||||||
self.config.write().await.selected_folder = None;
|
|
||||||
Err(Error::ConnectionLost)
|
|
||||||
}
|
|
||||||
Err(async_imap::error::Error::Validate(_)) => {
|
|
||||||
Err(Error::BadFolderName(folder.as_ref().to_string()))
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
self.config.write().await.selected_folder = None;
|
|
||||||
self.trigger_reconnect();
|
|
||||||
Err(Error::Other(err.to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(Error::NoSession)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_config_last_seen_uid<S: AsRef<str>>(&self, context: &Context, folder: S) -> (u32, u32) {
|
fn get_config_last_seen_uid<S: AsRef<str>>(&self, context: &Context, folder: S) -> (u32, u32) {
|
||||||
let key = format!("imap.mailbox.{}", folder.as_ref());
|
let key = format!("imap.mailbox.{}", folder.as_ref());
|
||||||
if let Some(entry) = context.sql.get_raw_config(context, &key) {
|
if let Some(entry) = context.sql.get_raw_config(context, &key) {
|
||||||
90
src/imap/select_folder.rs
Normal file
90
src/imap/select_folder.rs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
use super::{Result, Error, Imap};
|
||||||
|
use crate::context::Context;
|
||||||
|
|
||||||
|
impl Imap {
|
||||||
|
/// select a folder, possibly update uid_validity and, if needed,
|
||||||
|
/// expunge the folder to remove delete-marked messages.
|
||||||
|
pub(super) async fn select_folder<S: AsRef<str>>(
|
||||||
|
&self,
|
||||||
|
context: &Context,
|
||||||
|
folder: Option<S>,
|
||||||
|
) -> Result<()> {
|
||||||
|
if self.session.lock().await.is_none() {
|
||||||
|
let mut cfg = self.config.write().await;
|
||||||
|
cfg.selected_folder = None;
|
||||||
|
cfg.selected_folder_needs_expunge = false;
|
||||||
|
return Err(Error::NoSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is a new folder and the new folder is equal to the selected one, there's nothing to do.
|
||||||
|
// if there is _no_ new folder, we continue as we might want to expunge below.
|
||||||
|
if let Some(ref folder) = folder {
|
||||||
|
if let Some(ref selected_folder) = self.config.read().await.selected_folder {
|
||||||
|
if folder.as_ref() == selected_folder {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then)
|
||||||
|
let needs_expunge = { self.config.read().await.selected_folder_needs_expunge };
|
||||||
|
if needs_expunge {
|
||||||
|
if let Some(ref folder) = self.config.read().await.selected_folder {
|
||||||
|
info!(context, "Expunge messages in \"{}\".", folder);
|
||||||
|
|
||||||
|
// A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see
|
||||||
|
// https://tools.ietf.org/html/rfc3501#section-6.4.2
|
||||||
|
if let Some(ref mut session) = &mut *self.session.lock().await {
|
||||||
|
match session.close().await {
|
||||||
|
Ok(_) => {
|
||||||
|
info!(context, "close/expunge succeeded");
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
return Err(Error::CloseExpungeFailed(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::NoSession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.config.write().await.selected_folder_needs_expunge = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// select new folder
|
||||||
|
if let Some(ref folder) = folder {
|
||||||
|
if let Some(ref mut session) = &mut *self.session.lock().await {
|
||||||
|
let res = session.select(folder).await;
|
||||||
|
|
||||||
|
// https://tools.ietf.org/html/rfc3501#section-6.3.1
|
||||||
|
// says that if the server reports select failure we are in
|
||||||
|
// authenticated (not-select) state.
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(mailbox) => {
|
||||||
|
let mut config = self.config.write().await;
|
||||||
|
config.selected_folder = Some(folder.as_ref().to_string());
|
||||||
|
config.selected_mailbox = Some(mailbox);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(async_imap::error::Error::ConnectionLost) => {
|
||||||
|
self.trigger_reconnect();
|
||||||
|
self.config.write().await.selected_folder = None;
|
||||||
|
Err(Error::ConnectionLost)
|
||||||
|
}
|
||||||
|
Err(async_imap::error::Error::Validate(_)) => {
|
||||||
|
Err(Error::BadFolderName(folder.as_ref().to_string()))
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
self.config.write().await.selected_folder = None;
|
||||||
|
self.trigger_reconnect();
|
||||||
|
Err(Error::Other(err.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(Error::NoSession)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user