From a5cacb3f674aa94632720d98b7f59eadd2fd25aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Wed, 29 Nov 2023 11:04:25 +0100 Subject: [PATCH] build only used backends --- src/backend.rs | 359 +++++++++++++---------- src/domain/account/config.rs | 31 +- src/domain/email/envelope/config.rs | 43 ++- src/domain/email/envelope/flag/config.rs | 59 +++- src/domain/email/message/config.rs | 107 ++++++- src/domain/folder/config.rs | 91 +++++- src/main.rs | 43 ++- 7 files changed, 562 insertions(+), 171 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index 9284a77..b907263 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -47,7 +47,7 @@ use serde::{Deserialize, Serialize}; use crate::{account::TomlAccountConfig, Envelopes, IdMapper}; -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum BackendKind { #[default] @@ -124,145 +124,6 @@ pub struct BackendContext { pub sendmail: Option, } -pub struct Backend { - toml_account_config: TomlAccountConfig, - backend: email::backend::Backend, -} - -impl Backend { - fn build_id_mapper( - &self, - folder: &str, - backend_kind: Option<&BackendKind>, - ) -> Result { - let mut id_mapper = IdMapper::Dummy; - - match backend_kind { - Some(BackendKind::Maildir) => { - if let Some(mdir_config) = &self.toml_account_config.maildir { - id_mapper = IdMapper::new( - &self.backend.account_config, - folder, - mdir_config.root_dir.clone(), - )?; - } - } - Some(BackendKind::MaildirForSync) => { - id_mapper = IdMapper::new( - &self.backend.account_config, - folder, - self.backend.account_config.sync_dir()?, - )?; - } - #[cfg(feature = "notmuch-backend")] - Some(BackendKind::Notmuch) => { - if let Some(notmuch_config) = &self.toml_account_config.notmuch { - id_mapper = IdMapper::new( - &self.backend.account_config, - folder, - mdir_config.root_dir.clone(), - )?; - } - } - _ => (), - }; - - Ok(id_mapper) - } - - pub async fn list_envelopes( - &self, - folder: &str, - page_size: usize, - page: usize, - ) -> Result { - let backend_kind = self.toml_account_config.list_envelopes_kind(); - let id_mapper = self.build_id_mapper(folder, backend_kind)?; - let envelopes = self.backend.list_envelopes(folder, page_size, page).await?; - let envelopes = Envelopes::from_backend(&self.account_config, &id_mapper, envelopes)?; - Ok(envelopes) - } - - pub async fn add_flags(&self, folder: &str, ids: &[&str], flags: &Flags) -> Result<()> { - let backend_kind = self.toml_account_config.add_flags_kind(); - let id_mapper = self.build_id_mapper(folder, backend_kind)?; - let ids = Id::multiple(id_mapper.get_ids(ids)?); - self.backend.add_flags(folder, &ids, flags).await - } - - pub async fn set_flags(&self, folder: &str, ids: &[&str], flags: &Flags) -> Result<()> { - let backend_kind = self.toml_account_config.set_flags_kind(); - let id_mapper = self.build_id_mapper(folder, backend_kind)?; - let ids = Id::multiple(id_mapper.get_ids(ids)?); - self.backend.set_flags(folder, &ids, flags).await - } - - pub async fn remove_flags(&self, folder: &str, ids: &[&str], flags: &Flags) -> Result<()> { - let backend_kind = self.toml_account_config.remove_flags_kind(); - let id_mapper = self.build_id_mapper(folder, backend_kind)?; - let ids = Id::multiple(id_mapper.get_ids(ids)?); - self.backend.remove_flags(folder, &ids, flags).await - } - - pub async fn get_messages(&self, folder: &str, ids: &[&str]) -> Result { - let backend_kind = self.toml_account_config.get_messages_kind(); - let id_mapper = self.build_id_mapper(folder, backend_kind)?; - let ids = Id::multiple(id_mapper.get_ids(ids)?); - self.backend.get_messages(folder, &ids).await - } - - pub async fn copy_messages( - &self, - from_folder: &str, - to_folder: &str, - ids: &[&str], - ) -> Result<()> { - let backend_kind = self.toml_account_config.move_messages_kind(); - let id_mapper = self.build_id_mapper(from_folder, backend_kind)?; - let ids = Id::multiple(id_mapper.get_ids(ids)?); - self.backend - .copy_messages(from_folder, to_folder, &ids) - .await - } - - pub async fn move_messages( - &self, - from_folder: &str, - to_folder: &str, - ids: &[&str], - ) -> Result<()> { - let backend_kind = self.toml_account_config.move_messages_kind(); - let id_mapper = self.build_id_mapper(from_folder, backend_kind)?; - let ids = Id::multiple(id_mapper.get_ids(ids)?); - self.backend - .move_messages(from_folder, to_folder, &ids) - .await - } - - pub async fn delete_messages(&self, folder: &str, ids: &[&str]) -> Result<()> { - let backend_kind = self.toml_account_config.delete_messages_kind(); - let id_mapper = self.build_id_mapper(folder, backend_kind)?; - let ids = Id::multiple(id_mapper.get_ids(ids)?); - self.backend.delete_messages(folder, &ids).await - } - - pub async fn add_raw_message(&self, folder: &str, email: &[u8]) -> Result { - let backend_kind = self.toml_account_config.add_raw_message_kind(); - let id_mapper = self.build_id_mapper(folder, backend_kind)?; - let id = self.backend.add_raw_message(folder, email).await?; - id_mapper.create_alias(&*id)?; - Ok(id) - } -} - -impl Deref for Backend { - type Target = email::backend::Backend; - - fn deref(&self) -> &Self::Target { - &self.backend - } -} - pub struct BackendBuilder { toml_account_config: TomlAccountConfig, builder: email::backend::BackendBuilder, @@ -272,32 +133,64 @@ impl BackendBuilder { pub async fn new( toml_account_config: TomlAccountConfig, account_config: AccountConfig, + with_sending: bool, ) -> Result { + let used_backends = toml_account_config.get_used_backends(); + + let is_maildir_used = used_backends.contains(&BackendKind::Maildir); + let is_maildir_for_sync_used = used_backends.contains(&BackendKind::MaildirForSync); + #[cfg(feature = "imap-backend")] + let is_imap_used = used_backends.contains(&BackendKind::Imap); + #[cfg(feature = "notmuch-backend")] + let is_notmuch_used = used_backends.contains(&BackendKind::Notmuch); + #[cfg(feature = "smtp-sender")] + let is_smtp_used = used_backends.contains(&BackendKind::Smtp); + let is_sendmail_used = used_backends.contains(&BackendKind::Sendmail); + let backend_ctx_builder = BackendContextBuilder { - maildir: toml_account_config.maildir.as_ref().map(|mdir_config| { - MaildirSessionBuilder::new(account_config.clone(), mdir_config.clone()) - }), - maildir_for_sync: Some(MaildirSessionBuilder::new( - account_config.clone(), - MaildirConfig { - root_dir: account_config.sync_dir()?, - }, - )), + maildir: toml_account_config + .maildir + .as_ref() + .filter(|_| is_maildir_used) + .map(|mdir_config| { + MaildirSessionBuilder::new(account_config.clone(), mdir_config.clone()) + }), + maildir_for_sync: Some(MaildirConfig { + root_dir: account_config.sync_dir()?, + }) + .filter(|_| is_maildir_for_sync_used) + .map(|mdir_config| MaildirSessionBuilder::new(account_config.clone(), mdir_config)), + #[cfg(feature = "imap-backend")] - imap: toml_account_config.imap.as_ref().map(|imap_config| { - ImapSessionBuilder::new(account_config.clone(), imap_config.clone()) - }), + imap: toml_account_config + .imap + .as_ref() + .filter(|_| is_imap_used) + .map(|imap_config| { + ImapSessionBuilder::new(account_config.clone(), imap_config.clone()) + }), #[cfg(feature = "notmuch-backend")] - notmuch: toml_account_config.notmuch.as_ref().map(|notmuch_config| { - NotmuchSessionBuilder::new(account_config.clone(), notmuch_config.clone()) - }), + notmuch: toml_account_config + .notmuch + .as_ref() + .filter(|_| is_notmuch_used) + .map(|notmuch_config| { + NotmuchSessionBuilder::new(account_config.clone(), notmuch_config.clone()) + }), #[cfg(feature = "smtp-sender")] - smtp: toml_account_config.smtp.as_ref().map(|smtp_config| { - SmtpClientBuilder::new(account_config.clone(), smtp_config.clone()) - }), + smtp: toml_account_config + .smtp + .as_ref() + .filter(|_| with_sending) + .filter(|_| is_smtp_used) + .map(|smtp_config| { + SmtpClientBuilder::new(account_config.clone(), smtp_config.clone()) + }), sendmail: toml_account_config .sendmail .as_ref() + .filter(|_| with_sending) + .filter(|_| is_sendmail_used) .map(|sendmail_config| { SendmailContext::new(account_config.clone(), sendmail_config.clone()) }), @@ -734,3 +627,153 @@ impl Into> for BackendBuil self.builder } } + +pub struct Backend { + toml_account_config: TomlAccountConfig, + backend: email::backend::Backend, +} + +impl Backend { + pub async fn new( + toml_account_config: TomlAccountConfig, + account_config: AccountConfig, + with_sending: bool, + ) -> Result { + BackendBuilder::new(toml_account_config, account_config, with_sending) + .await? + .build() + .await + } + + fn build_id_mapper( + &self, + folder: &str, + backend_kind: Option<&BackendKind>, + ) -> Result { + let mut id_mapper = IdMapper::Dummy; + + match backend_kind { + Some(BackendKind::Maildir) => { + if let Some(mdir_config) = &self.toml_account_config.maildir { + id_mapper = IdMapper::new( + &self.backend.account_config, + folder, + mdir_config.root_dir.clone(), + )?; + } + } + Some(BackendKind::MaildirForSync) => { + id_mapper = IdMapper::new( + &self.backend.account_config, + folder, + self.backend.account_config.sync_dir()?, + )?; + } + #[cfg(feature = "notmuch-backend")] + Some(BackendKind::Notmuch) => { + if let Some(notmuch_config) = &self.toml_account_config.notmuch { + id_mapper = IdMapper::new( + &self.backend.account_config, + folder, + mdir_config.root_dir.clone(), + )?; + } + } + _ => (), + }; + + Ok(id_mapper) + } + + pub async fn list_envelopes( + &self, + folder: &str, + page_size: usize, + page: usize, + ) -> Result { + let backend_kind = self.toml_account_config.list_envelopes_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let envelopes = self.backend.list_envelopes(folder, page_size, page).await?; + let envelopes = Envelopes::from_backend(&self.account_config, &id_mapper, envelopes)?; + Ok(envelopes) + } + + pub async fn add_flags(&self, folder: &str, ids: &[&str], flags: &Flags) -> Result<()> { + let backend_kind = self.toml_account_config.add_flags_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let ids = Id::multiple(id_mapper.get_ids(ids)?); + self.backend.add_flags(folder, &ids, flags).await + } + + pub async fn set_flags(&self, folder: &str, ids: &[&str], flags: &Flags) -> Result<()> { + let backend_kind = self.toml_account_config.set_flags_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let ids = Id::multiple(id_mapper.get_ids(ids)?); + self.backend.set_flags(folder, &ids, flags).await + } + + pub async fn remove_flags(&self, folder: &str, ids: &[&str], flags: &Flags) -> Result<()> { + let backend_kind = self.toml_account_config.remove_flags_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let ids = Id::multiple(id_mapper.get_ids(ids)?); + self.backend.remove_flags(folder, &ids, flags).await + } + + pub async fn get_messages(&self, folder: &str, ids: &[&str]) -> Result { + let backend_kind = self.toml_account_config.get_messages_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let ids = Id::multiple(id_mapper.get_ids(ids)?); + self.backend.get_messages(folder, &ids).await + } + + pub async fn copy_messages( + &self, + from_folder: &str, + to_folder: &str, + ids: &[&str], + ) -> Result<()> { + let backend_kind = self.toml_account_config.move_messages_kind(); + let id_mapper = self.build_id_mapper(from_folder, backend_kind)?; + let ids = Id::multiple(id_mapper.get_ids(ids)?); + self.backend + .copy_messages(from_folder, to_folder, &ids) + .await + } + + pub async fn move_messages( + &self, + from_folder: &str, + to_folder: &str, + ids: &[&str], + ) -> Result<()> { + let backend_kind = self.toml_account_config.move_messages_kind(); + let id_mapper = self.build_id_mapper(from_folder, backend_kind)?; + let ids = Id::multiple(id_mapper.get_ids(ids)?); + self.backend + .move_messages(from_folder, to_folder, &ids) + .await + } + + pub async fn delete_messages(&self, folder: &str, ids: &[&str]) -> Result<()> { + let backend_kind = self.toml_account_config.delete_messages_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let ids = Id::multiple(id_mapper.get_ids(ids)?); + self.backend.delete_messages(folder, &ids).await + } + + pub async fn add_raw_message(&self, folder: &str, email: &[u8]) -> Result { + let backend_kind = self.toml_account_config.add_raw_message_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let id = self.backend.add_raw_message(folder, email).await?; + id_mapper.create_alias(&*id)?; + Ok(id) + } +} + +impl Deref for Backend { + type Target = email::backend::Backend; + + fn deref(&self) -> &Self::Target { + &self.backend + } +} diff --git a/src/domain/account/config.rs b/src/domain/account/config.rs index f64396f..d514396 100644 --- a/src/domain/account/config.rs +++ b/src/domain/account/config.rs @@ -16,7 +16,10 @@ use email::{ sendmail::SendmailConfig, }; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, path::PathBuf}; +use std::{ + collections::{HashMap, HashSet}, + path::PathBuf, +}; use crate::{ backend::BackendKind, @@ -223,4 +226,30 @@ impl TomlAccountConfig { .and_then(|send| send.backend.as_ref()) .or_else(|| self.backend.as_ref()) } + + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut used_backends = HashSet::default(); + + if let Some(ref kind) = self.backend { + used_backends.insert(kind); + } + + if let Some(ref folder) = self.folder { + used_backends.extend(folder.get_used_backends()); + } + + if let Some(ref envelope) = self.envelope { + used_backends.extend(envelope.get_used_backends()); + } + + if let Some(ref flag) = self.flag { + used_backends.extend(flag.get_used_backends()); + } + + if let Some(ref msg) = self.message { + used_backends.extend(msg.get_used_backends()); + } + + used_backends + } } diff --git a/src/domain/email/envelope/config.rs b/src/domain/email/envelope/config.rs index 35a5629..fa7f5d8 100644 --- a/src/domain/email/envelope/config.rs +++ b/src/domain/email/envelope/config.rs @@ -1,4 +1,5 @@ -use ::serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; use crate::backend::BackendKind; @@ -8,12 +9,52 @@ pub struct EnvelopeConfig { pub get: Option, } +impl EnvelopeConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(list) = &self.list { + kinds.extend(list.get_used_backends()); + } + + if let Some(get) = &self.get { + kinds.extend(get.get_used_backends()); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct EnvelopeListConfig { pub backend: Option, } +impl EnvelopeListConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct EnvelopeGetConfig { pub backend: Option, } + +impl EnvelopeGetConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} diff --git a/src/domain/email/envelope/flag/config.rs b/src/domain/email/envelope/flag/config.rs index af01500..eb75af4 100644 --- a/src/domain/email/envelope/flag/config.rs +++ b/src/domain/email/envelope/flag/config.rs @@ -1,4 +1,5 @@ -use ::serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; use crate::backend::BackendKind; @@ -9,17 +10,73 @@ pub struct FlagConfig { pub remove: Option, } +impl FlagConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(add) = &self.add { + kinds.extend(add.get_used_backends()); + } + + if let Some(set) = &self.set { + kinds.extend(set.get_used_backends()); + } + + if let Some(remove) = &self.remove { + kinds.extend(remove.get_used_backends()); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FlagAddConfig { pub backend: Option, } +impl FlagAddConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FlagSetConfig { pub backend: Option, } +impl FlagSetConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FlagRemoveConfig { pub backend: Option, } + +impl FlagRemoveConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} diff --git a/src/domain/email/message/config.rs b/src/domain/email/message/config.rs index abb2072..0ab96a4 100644 --- a/src/domain/email/message/config.rs +++ b/src/domain/email/message/config.rs @@ -1,4 +1,5 @@ -use ::serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; use crate::backend::BackendKind; @@ -13,32 +14,136 @@ pub struct MessageConfig { pub move_: Option, } +impl MessageConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(add) = &self.add { + kinds.extend(add.get_used_backends()); + } + + if let Some(send) = &self.send { + kinds.extend(send.get_used_backends()); + } + + if let Some(peek) = &self.peek { + kinds.extend(peek.get_used_backends()); + } + + if let Some(get) = &self.get { + kinds.extend(get.get_used_backends()); + } + + if let Some(copy) = &self.copy { + kinds.extend(copy.get_used_backends()); + } + + if let Some(move_) = &self.move_ { + kinds.extend(move_.get_used_backends()); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageAddConfig { pub backend: Option, } +impl MessageAddConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageSendConfig { pub backend: Option, } +impl MessageSendConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessagePeekConfig { pub backend: Option, } +impl MessagePeekConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageGetConfig { pub backend: Option, } +impl MessageGetConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageCopyConfig { pub backend: Option, } +impl MessageCopyConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageMoveConfig { pub backend: Option, } + +impl MessageMoveConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} diff --git a/src/domain/folder/config.rs b/src/domain/folder/config.rs index 105db57..16250f9 100644 --- a/src/domain/folder/config.rs +++ b/src/domain/folder/config.rs @@ -1,4 +1,5 @@ -use ::serde::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; use crate::backend::BackendKind; @@ -11,27 +12,115 @@ pub struct FolderConfig { pub delete: Option, } +impl FolderConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(add) = &self.add { + kinds.extend(add.get_used_backends()); + } + + if let Some(list) = &self.list { + kinds.extend(list.get_used_backends()); + } + + if let Some(expunge) = &self.expunge { + kinds.extend(expunge.get_used_backends()); + } + + if let Some(purge) = &self.purge { + kinds.extend(purge.get_used_backends()); + } + + if let Some(delete) = &self.delete { + kinds.extend(delete.get_used_backends()); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderAddConfig { pub backend: Option, } +impl FolderAddConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderListConfig { pub backend: Option, } +impl FolderListConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderExpungeConfig { pub backend: Option, } +impl FolderExpungeConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderPurgeConfig { pub backend: Option, } +impl FolderPurgeConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderDeleteConfig { pub backend: Option, } + +impl FolderDeleteConfig { + pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + let mut kinds = HashSet::default(); + + if let Some(kind) = &self.backend { + kinds.insert(kind); + } + + kinds + } +} diff --git a/src/main.rs b/src/main.rs index 2cd9433..18213e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use url::Url; use himalaya::imap; use himalaya::{ account, - backend::BackendBuilder, + backend::{Backend, BackendBuilder}, cache, compl, config::{self, TomlConfig}, email, flag, folder, man, output, @@ -61,7 +61,7 @@ async fn main() -> Result<()> { .await? .into_account_configs(None, false)?; let backend_builder = - BackendBuilder::new(toml_account_config, account_config.clone()).await?; + BackendBuilder::new(toml_account_config, account_config.clone(), true).await?; let backend = backend_builder.build().await?; let mut printer = StdoutPrinter::default(); @@ -130,7 +130,7 @@ async fn main() -> Result<()> { .clone() .into_account_configs(maybe_account_name, true)?; let backend_builder = - BackendBuilder::new(toml_account_config, account_config.clone()).await?; + BackendBuilder::new(toml_account_config, account_config.clone(), false).await?; let sync_builder = AccountSyncBuilder::new(backend_builder.into()) .await? .with_some_folders_strategy(strategy) @@ -149,28 +149,29 @@ async fn main() -> Result<()> { let (toml_account_config, account_config) = toml_config .clone() .into_account_configs(maybe_account_name, disable_cache)?; - println!("toml_account_config: {:#?}", toml_account_config); - let backend_builder = BackendBuilder::new(toml_account_config, account_config.clone()).await?; - let backend = backend_builder.build().await?; // checks folder commands match folder::args::matches(&m)? { Some(folder::args::Cmd::Create) => { + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; let folder = folder .ok_or_else(|| anyhow!("the folder argument is missing")) .context("cannot create folder")?; return folder::handlers::create(&mut printer, &backend, &folder).await; } Some(folder::args::Cmd::List(max_width)) => { + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return folder::handlers::list(&account_config, &mut printer, &backend, max_width) .await; } Some(folder::args::Cmd::Expunge) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return folder::handlers::expunge(&mut printer, &backend, &folder).await; } Some(folder::args::Cmd::Delete) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return folder::handlers::delete(&mut printer, &backend, &folder).await; } _ => (), @@ -180,6 +181,7 @@ async fn main() -> Result<()> { match email::args::matches(&m)? { Some(email::args::Cmd::Attachments(ids)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::attachments( &account_config, &mut printer, @@ -191,14 +193,17 @@ async fn main() -> Result<()> { } Some(email::args::Cmd::Copy(ids, to_folder)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::copy(&mut printer, &backend, &folder, to_folder, ids).await; } Some(email::args::Cmd::Delete(ids)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::delete(&mut printer, &backend, &folder, ids).await; } Some(email::args::Cmd::Forward(id, headers, body)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; return email::handlers::forward( &account_config, &mut printer, @@ -212,6 +217,7 @@ async fn main() -> Result<()> { } Some(email::args::Cmd::List(max_width, page_size, page)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::list( &account_config, &mut printer, @@ -225,10 +231,12 @@ async fn main() -> Result<()> { } Some(email::args::Cmd::Move(ids, to_folder)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::move_(&mut printer, &backend, &folder, to_folder, ids).await; } Some(email::args::Cmd::Read(ids, text_mime, raw, headers)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::read( &account_config, &mut printer, @@ -243,6 +251,7 @@ async fn main() -> Result<()> { } Some(email::args::Cmd::Reply(id, all, headers, body)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; return email::handlers::reply( &account_config, &mut printer, @@ -257,10 +266,12 @@ async fn main() -> Result<()> { } Some(email::args::Cmd::Save(raw_email)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::save(&mut printer, &backend, &folder, raw_email).await; } Some(email::args::Cmd::Search(query, max_width, page_size, page)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::search( &account_config, &mut printer, @@ -275,6 +286,7 @@ async fn main() -> Result<()> { } Some(email::args::Cmd::Sort(criteria, query, max_width, page_size, page)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; return email::handlers::sort( &account_config, &mut printer, @@ -289,19 +301,26 @@ async fn main() -> Result<()> { .await; } Some(email::args::Cmd::Send(raw_email)) => { + let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; return email::handlers::send(&account_config, &mut printer, &backend, raw_email).await; } Some(email::args::Cmd::Flag(m)) => match m { Some(flag::args::Cmd::Set(ids, ref flags)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = + Backend::new(toml_account_config, account_config.clone(), false).await?; return flag::handlers::set(&mut printer, &backend, &folder, ids, flags).await; } Some(flag::args::Cmd::Add(ids, ref flags)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = + Backend::new(toml_account_config, account_config.clone(), false).await?; return flag::handlers::add(&mut printer, &backend, &folder, ids, flags).await; } Some(flag::args::Cmd::Remove(ids, ref flags)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = + Backend::new(toml_account_config, account_config.clone(), false).await?; return flag::handlers::remove(&mut printer, &backend, &folder, ids, flags).await; } _ => (), @@ -309,6 +328,8 @@ async fn main() -> Result<()> { Some(email::args::Cmd::Tpl(m)) => match m { Some(tpl::args::Cmd::Forward(id, headers, body)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = + Backend::new(toml_account_config, account_config.clone(), false).await?; return tpl::handlers::forward( &account_config, &mut printer, @@ -321,11 +342,12 @@ async fn main() -> Result<()> { .await; } Some(tpl::args::Cmd::Write(headers, body)) => { - tpl::handlers::write(&account_config, &mut printer, headers, body).await?; - return Ok(()); + return tpl::handlers::write(&account_config, &mut printer, headers, body).await; } Some(tpl::args::Cmd::Reply(id, all, headers, body)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = + Backend::new(toml_account_config, account_config.clone(), false).await?; return tpl::handlers::reply( &account_config, &mut printer, @@ -340,15 +362,20 @@ async fn main() -> Result<()> { } Some(tpl::args::Cmd::Save(tpl)) => { let folder = folder.unwrap_or(DEFAULT_INBOX_FOLDER); + let backend = + Backend::new(toml_account_config, account_config.clone(), false).await?; return tpl::handlers::save(&account_config, &mut printer, &backend, &folder, tpl) .await; } Some(tpl::args::Cmd::Send(tpl)) => { + let backend = + Backend::new(toml_account_config, account_config.clone(), true).await?; return tpl::handlers::send(&account_config, &mut printer, &backend, tpl).await; } _ => (), }, Some(email::args::Cmd::Write(headers, body)) => { + let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; return email::handlers::write(&account_config, &mut printer, &backend, headers, body) .await; }