From 4d4e189cb98bd12b58fa8f5cd694ca6a143e175c Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 4 Aug 2024 13:39:10 +0300 Subject: [PATCH] imap: code style fixups Signed-off-by: Manos Pitsidianakis --- melib/src/imap/mailbox.rs | 2 +- melib/src/imap/mod.rs | 4 +-- melib/src/imap/protocol_parser.rs | 2 +- melib/src/imap/sync/mod.rs | 54 ++++++++++++++++------------ melib/src/imap/sync/sqlite3_cache.rs | 22 ++++++++++++ melib/src/imap/watch.rs | 17 ++++----- 6 files changed, 65 insertions(+), 36 deletions(-) diff --git a/melib/src/imap/mailbox.rs b/melib/src/imap/mailbox.rs index a050b968..a7ee5735 100644 --- a/melib/src/imap/mailbox.rs +++ b/melib/src/imap/mailbox.rs @@ -21,12 +21,12 @@ use std::sync::{Arc, Mutex, RwLock}; -use super::protocol_parser::SelectResponse; use crate::{ backends::{ BackendMailbox, LazyCountSet, Mailbox, MailboxHash, MailboxPermissions, SpecialUsageMailbox, }, error::*, + imap::protocol_parser::SelectResponse, }; #[derive(Clone, Debug, Default)] diff --git a/melib/src/imap/mod.rs b/melib/src/imap/mod.rs index be6eb3cb..0e11023f 100644 --- a/melib/src/imap/mod.rs +++ b/melib/src/imap/mod.rs @@ -1423,7 +1423,7 @@ impl ImapType { #[cfg(not(feature = "sqlite3"))] if keep_offline_cache { return Err(Error::new(format!( - "({}) keep_offline_cache is true but melib is not compiled with sqlite3", + "({}) offline_cache is true but melib is not compiled with sqlite3", s.name, ))); } @@ -1710,7 +1710,7 @@ impl ImapType { let keep_offline_cache = get_conf_val!(s["offline_cache"], false)?; if keep_offline_cache { return Err(Error::new(format!( - "({}) keep_offline_cache is true but melib is not compiled with sqlite3", + "({}) offline_cache is true but melib is not compiled with sqlite3", s.name, ))); } diff --git a/melib/src/imap/protocol_parser.rs b/melib/src/imap/protocol_parser.rs index fa876478..d8363391 100644 --- a/melib/src/imap/protocol_parser.rs +++ b/melib/src/imap/protocol_parser.rs @@ -992,7 +992,7 @@ pub struct SelectResponse { pub uidvalidity: UIDVALIDITY, pub uidnext: UID, pub permanentflags: (Flag, Vec), - /// if SELECT returns \* we can set arbitrary flags permanently. + /// if `SELECT` returns `\*` we can set arbitrary flags permanently. pub can_create_flags: bool, pub read_only: bool, pub highestmodseq: Option>, diff --git a/melib/src/imap/sync/mod.rs b/melib/src/imap/sync/mod.rs index 7cd804d2..36b7d9fe 100644 --- a/melib/src/imap/sync/mod.rs +++ b/melib/src/imap/sync/mod.rs @@ -36,8 +36,11 @@ pub mod sqlite3_cache; impl ImapConnection { pub async fn resync(&mut self, mailbox_hash: MailboxHash) -> Result>> { - debug!("resync mailbox_hash {}", mailbox_hash); - debug!(&self.sync_policy); + log::trace!( + "resync mailbox_hash {} with policy {:?}", + mailbox_hash, + self.sync_policy + ); if matches!(self.sync_policy, SyncPolicy::None) { return Ok(None); } @@ -62,7 +65,7 @@ impl ImapConnection { } pub async fn load_cache(&self, mailbox_hash: MailboxHash) -> Option>> { - debug!("load_cache {}", mailbox_hash); + log::trace!("load_cache {}", mailbox_hash); let mut cache_handle = match self.uid_store.cache_handle() { Ok(v) => v?, Err(err) => return Some(Err(err)), @@ -81,14 +84,16 @@ impl ImapConnection { } } - /// RFC4549 Synchronization Operations for Disconnected IMAP4 Clients + /// Re-sync IMAP state by following the strategy described in + /// [RFC4549](https://datatracker.ietf.org/doc/rfc4549/) "Synchronization Operations for + /// Disconnected IMAP4 Clients". pub async fn resync_basic( &mut self, mut cache_handle: Box, mailbox_hash: MailboxHash, ) -> Result>> { + log::trace!("resync_basic mailbox_hash {:?}", mailbox_hash); let mut payload = vec![]; - debug!("resync_basic"); let mut response = Vec::with_capacity(8 * 1024); let cached_uidvalidity = self .uid_store @@ -132,6 +137,10 @@ impl ImapConnection { cache_handle.update_mailbox(mailbox_hash, &select_response)?; // 2. tag1 UID FETCH :* + log::trace!( + "Step 2. tag1 UID FETCH :* == {}:*", + max_uid + 1 + ); self.send_command(CommandBody::fetch( max_uid + 1.., common_attributes(), @@ -140,13 +149,13 @@ impl ImapConnection { .await?; self.read_response(&mut response, RequiredResponses::FETCH_REQUIRED) .await?; - debug!( + log::debug!( "fetch response is {} bytes and {} lines", response.len(), String::from_utf8_lossy(&response).lines().count() ); let (_, mut v, _) = protocol_parser::fetch_responses(&response)?; - debug!("responses len is {}", v.len()); + log::debug!("responses len is {}", v.len()); for FetchResponse { ref uid, ref mut envelope, @@ -194,15 +203,6 @@ impl ImapConnection { { let uid = uid.unwrap(); let env = envelope.unwrap(); - /* - debug!( - "env hash {} {} UID = {} MSN = {}", - env.hash(), - env.subject(), - uid, - message_sequence_number - ); - */ self.uid_store .hash_index .lock() @@ -215,7 +215,6 @@ impl ImapConnection { .insert((mailbox_hash, uid), env.hash()); payload.push((uid, env)); } - debug!("sending payload for {}", mailbox_hash); let payload_hash_set: BTreeSet<_> = payload.iter().map(|(_, env)| env.hash()).collect::<_>(); { @@ -241,6 +240,7 @@ impl ImapConnection { } } // 3. tag2 UID FETCH 1: FLAGS + log::trace!("Step 3. tag2 UID FETCH 1: FLAGS"); let sequence_set = if max_uid == 0 { SequenceSet::from(..) } else { @@ -326,15 +326,18 @@ impl ImapConnection { Ok(Some(payload.into_iter().map(|(_, env)| env).collect())) } - /// RFC4549 Synchronization Operations for Disconnected IMAP4 Clients - /// > Section 6.1 + /// Resync with `CONDSTORE` Extension + /// + /// Re-sync IMAP state by following the strategy described in + /// [RFC4549](https://datatracker.ietf.org/doc/rfc4549/) "Synchronization Operations for + /// Disconnected IMAP4 Clients", Section 6.1 "CONDSTORE Extension" pub async fn resync_condstore( &mut self, mut cache_handle: Box, mailbox_hash: MailboxHash, ) -> Result>> { + log::trace!("resync_condstore: mailbox_hash {:?}", mailbox_hash); let mut payload = vec![]; - debug!("resync_condstore"); let mut response = Vec::with_capacity(8 * 1024); let cached_uidvalidity = self .uid_store @@ -648,13 +651,20 @@ impl ImapConnection { Ok(Some(payload.into_iter().map(|(_, env)| env).collect())) } - /// RFC7162 Quick Flag Changes Resynchronization (CONDSTORE) and Quick - /// Mailbox Resynchronization (QRESYNC) + /// Resync with `CONDSTORE` and `QRESYNC` Extension + /// + /// Re-sync IMAP state by following the strategy described in + /// [RFC7162](https://datatracker.ietf.org/doc/rfc7162/) "Quick Flag Changes Resynchronization (CONDSTORE) and Quick + /// Mailbox Resynchronization (QRESYNC)" pub async fn resync_condstoreqresync( &self, _cache_handle: Box, _mailbox_hash: MailboxHash, ) -> Result>> { + log::trace!( + "resync_condstoreqresync: mailbox_hash: {:?}, function unimplemented", + _mailbox_hash + ); Ok(None) } diff --git a/melib/src/imap/sync/sqlite3_cache.rs b/melib/src/imap/sync/sqlite3_cache.rs index f0b8830b..4c47c2c6 100644 --- a/melib/src/imap/sync/sqlite3_cache.rs +++ b/melib/src/imap/sync/sqlite3_cache.rs @@ -431,6 +431,13 @@ impl ImapCache for Sqlite3Cache { .cloned() .unwrap_or_default(); if self.mailbox_state(mailbox_hash)?.is_none() { + log::trace!( + "insert_envelopes: Mailbox not in cache, mailbox_hash: {:?}, fetches: {:?} \ + backtrace:\n{}", + mailbox_hash, + fetches, + std::backtrace::Backtrace::capture() + ); return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::NotFound)); } let Self { @@ -490,6 +497,14 @@ impl ImapCache for Sqlite3Cache { flags: SmallVec<[FlagOp; 8]>, ) -> Result<()> { if self.mailbox_state(mailbox_hash)?.is_none() { + log::trace!( + "update_flags: Mailbox not in cache, env_hashes: {:?}, mailbox_hash: {:?} flags \ + {:?} backtrace:\n{}", + env_hashes, + mailbox_hash, + flags, + std::backtrace::Backtrace::capture() + ); return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::NotFound)); } let Self { @@ -549,6 +564,13 @@ impl ImapCache for Sqlite3Cache { refresh_events: &[(UID, RefreshEvent)], ) -> Result<()> { if self.mailbox_state(mailbox_hash)?.is_none() { + log::trace!( + "update: Mailbox not in cache, mailbox_hash: {:?}, refresh_events: {:?} \ + backtrace:\n{}", + mailbox_hash, + refresh_events, + std::backtrace::Backtrace::capture() + ); return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::NotFound)); } { diff --git a/melib/src/imap/watch.rs b/melib/src/imap/watch.rs index 42acaacd..d7148d9c 100644 --- a/melib/src/imap/watch.rs +++ b/melib/src/imap/watch.rs @@ -200,7 +200,7 @@ pub async fn examine_updates( return Ok(()); } let mailbox_hash = mailbox.hash(); - debug!("examining mailbox {} {}", mailbox_hash, mailbox.path()); + log::debug!("examining mailbox {} {}", mailbox_hash, mailbox.path()); if let Some(new_envelopes) = conn.resync(mailbox_hash).await? { for env in new_envelopes { conn.add_refresh_event(RefreshEvent { @@ -230,17 +230,14 @@ pub async fn examine_updates( mailbox_hash, kind: RefreshEventKind::Rescan, }); - /* - uid_store.uid_index.lock().unwrap().clear(); - uid_store.hash_index.lock().unwrap().clear(); - uid_store.byte_cache.lock().unwrap().clear(); - */ return Ok(()); } } else { uidvalidities.insert(mailbox_hash, select_response.uidvalidity); } } + + let current_exists = mailbox.exists.lock().unwrap().len(); if mailbox.is_cold() { /* Mailbox hasn't been loaded yet */ let has_list_status: bool = conn @@ -328,8 +325,8 @@ pub async fn examine_updates( .await?; conn.read_response(&mut response, RequiredResponses::FETCH_REQUIRED) .await?; - } else if select_response.exists > mailbox.exists.lock().unwrap().len() { - let min = std::cmp::max(mailbox.exists.lock().unwrap().len(), 1); + } else if select_response.exists > current_exists { + let min = current_exists.max(1); conn.send_command(CommandBody::fetch(min.., common_attributes(), false)?) .await?; @@ -338,13 +335,13 @@ pub async fn examine_updates( } else { return Ok(()); } - debug!( + log::debug!( "fetch response is {} bytes and {} lines", response.len(), String::from_utf8_lossy(&response).lines().count() ); let (_, mut v, _) = protocol_parser::fetch_responses(&response)?; - debug!("responses len is {}", v.len()); + log::debug!("responses len is {}", v.len()); for FetchResponse { ref uid, ref mut envelope,