diff --git a/src/imap/idle.rs b/src/imap/idle.rs index 30e27b9ee..d437e1619 100644 --- a/src/imap/idle.rs +++ b/src/imap/idle.rs @@ -59,7 +59,7 @@ impl Imap { task::block_on(async move { self.config.read().await.can_idle }) } - pub fn idle(&self, context: &Context, watch_folder: Option) -> Result<()> { + pub fn idle(&self, context: &Context, watch_folder: String) -> Result<()> { task::block_on(async move { if !self.can_idle() { return Err(Error::IdleAbilityMissing); @@ -67,7 +67,7 @@ impl Imap { self.setup_handle_if_needed(context).await?; - self.select_folder(context, watch_folder.clone()).await?; + self.select_folder(context, watch_folder).await?; let session = self.session.lock().await.take(); let timeout = Duration::from_secs(23 * 60); diff --git a/src/imap/mod.rs b/src/imap/mod.rs index b86b8c39e..204a0157c 100644 --- a/src/imap/mod.rs +++ b/src/imap/mod.rs @@ -476,7 +476,7 @@ impl Imap { folder: &str, ) -> Result<(u32, u32)> { task::block_on(async move { - self.select_folder(context, Some(folder)).await?; + self.select_folder(context, folder).await?; // compare last seen UIDVALIDITY against the current one let (uid_validity, last_seen_uid) = self.get_config_last_seen_uid(context, &folder); @@ -912,7 +912,7 @@ impl Imap { return Some(ImapActionResult::RetryLater); } } - match self.select_folder(context, Some(&folder)).await { + match self.select_folder(context, &folder).await { Ok(()) => None, Err(select_folder::Error::ConnectionLost) => { warn!(context, "Lost imap connection"); @@ -1183,7 +1183,7 @@ impl Imap { error!(context, "could not setup imap connection: {}", err); return; } - if let Err(err) = self.select_folder(context, Some(&folder)).await { + if let Err(err) = self.select_folder(context, &folder).await { error!( context, "Could not select {} for expunging: {}", folder, err @@ -1201,7 +1201,7 @@ impl Imap { // we now trigger expunge to actually delete messages self.config.write().await.selected_folder_needs_expunge = true; - match self.select_folder::(context, None).await { + match self.select_folder(context, &folder).await { Ok(()) => { emit_event!(context, Event::ImapFolderEmptied(folder.to_string())); } diff --git a/src/imap/select_folder.rs b/src/imap/select_folder.rs index 4d454c332..e0fce0dff 100644 --- a/src/imap/select_folder.rs +++ b/src/imap/select_folder.rs @@ -56,7 +56,7 @@ impl Imap { pub(super) async fn select_folder>( &self, context: &Context, - folder: Option, + folder: S, ) -> Result<()> { if self.session.lock().await.is_none() { let mut cfg = self.config.write().await; @@ -71,46 +71,41 @@ impl Imap { self.close_folder(context).await?; } - let folder_str: Option<&str> = folder.as_ref().map(|x| x.as_ref()); - if self.config.read().await.selected_folder.as_deref() == folder_str { + if self.config.read().await.selected_folder.as_deref() == Some(folder.as_ref()) { return Ok(()); } // 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; + 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. + // 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())) - } + 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(()) + Err(Error::NoSession) } } } diff --git a/src/job_thread.rs b/src/job_thread.rs index 12512a3d6..0e524e161 100644 --- a/src/job_thread.rs +++ b/src/job_thread.rs @@ -173,14 +173,15 @@ impl JobThread { if !self.imap.can_idle() { true // we have to do fake_idle } else { - let watch_folder = self.get_watch_folder(context); - info!(context, "{} started...", prefix); - let res = self.imap.idle(context, watch_folder); - info!(context, "{} ended...", prefix); - if let Err(err) = res { - warn!(context, "{} failed: {} -> reconnecting", prefix, err); - // something is borked, let's start afresh on the next occassion - self.imap.disconnect(context); + if let Some(watch_folder) = self.get_watch_folder(context) { + info!(context, "{} started...", prefix); + let res = self.imap.idle(context, watch_folder); + info!(context, "{} ended...", prefix); + if let Err(err) = res { + warn!(context, "{} failed: {} -> reconnecting", prefix, err); + // something is Label { Label }orked, let's start afresh on the next occassion + self.imap.disconnect(context); + } } false }