diff --git a/CHANGELOG.md b/CHANGELOG.md index af01fd4..d00579b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added one cargo feature per backend feature: + - TODO + +### Changed + +- Renamed `folder create` to `folder add` in order to better match types. An alias has been set up, so both `create` and `add` still work. + ### Fixed - Fixed default command: running `himalaya` without argument lists envelopes, as it used to be in previous versions. diff --git a/Cargo.lock b/Cargo.lock index 6c1001e..02eba7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1216,9 +1216,8 @@ dependencies = [ [[package]] name = "email-lib" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e4c31e26febefc822561fe388677cec106bbf0a7fe16608e7638daa3d1da9d9" +version = "0.19.6" +source = "git+https://git.sr.ht/~soywod/pimalaya#2933075a179bfff3349987e9620185799eeba907" dependencies = [ "advisory-lock", "anyhow", @@ -1235,7 +1234,6 @@ dependencies = [ "mail-parser", "mail-send", "maildirpp", - "md5", "mml-lib", "notify", "notify-rust", @@ -1248,8 +1246,6 @@ dependencies = [ "rayon", "regex", "rusqlite", - "rustls 0.22.1", - "rustls-native-certs", "secret-lib", "serde", "shellexpand-utils", @@ -1259,8 +1255,6 @@ dependencies = [ "tree_magic_mini", "urlencoding", "utf7-imap", - "uuid", - "webpki-roots 0.25.3", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7d1e644..cdf8ac4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,24 +17,79 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = [ - "maildir", "imap", + "maildir", # "notmuch", "smtp", "sendmail", + "account", + "folder", + "envelope", + "flag", + "message", + "attachment", + "template", + "sync", # "pgp-commands", # "pgp-gpg", # "pgp-native", ] -maildir = ["email-lib/maildir"] imap = ["email-lib/imap"] +maildir = ["email-lib/maildir"] notmuch = ["email-lib/notmuch"] smtp = ["email-lib/smtp"] sendmail = ["email-lib/sendmail"] +account = ["account-configure", "account-list"] +account-command = [] +account-configure = ["account-command"] +account-list = ["account-command"] +folder = ["folder-add", "folder-list", "folder-expunge", "folder-purge", "folder-delete"] +folder-command = [] +folder-add = ["folder-command", "email-lib/folder-add"] +folder-list = ["folder-command", "email-lib/folder-list"] +folder-expunge = ["folder-command", "email-lib/folder-expunge"] +folder-purge = ["folder-command", "email-lib/folder-purge"] +folder-delete = ["folder-command", "email-lib/folder-delete"] +envelope = ["envelope-list", "envelope-watch", "envelope-get"] +envelope-command = [] +envelope-list = ["envelope-command", "email-lib/envelope-list"] +envelope-watch = ["envelope-command", "email-lib/envelope-watch"] +envelope-get = ["envelope-command", "email-lib/envelope-get"] +flag = ["flag-add", "flag-set", "flag-remove"] +flag-command = [] +flag-add = ["flag-command", "email-lib/flag-add"] +flag-set = ["flag-command", "email-lib/flag-set"] +flag-remove = ["flag-command", "email-lib/flag-remove"] +message = ["message-read", "message-write", "message-mailto", "message-reply", "message-forward", "message-save", "message-send", "message-copy", "message-move", "message-delete"] +message-command = [] +message-add = ["email-lib/message-add"] +message-peek = ["email-lib/message-peek"] +message-get = ["email-lib/message-get"] +message-copy = ["message-command", "email-lib/message-copy"] +message-move = ["message-command", "email-lib/message-move"] +message-delete = ["message-command", "email-lib/message-delete"] +message-send = ["message-command", "email-lib/message-send"] +message-read = ["message-add", "message-peek", "message-get"] +message-write = ["message-add", "message-send"] +message-mailto = ["message-add", "message-send"] +message-reply = ["message-get", "message-add", "message-send"] +message-forward = ["message-get", "message-add", "message-send"] +message-save = ["message-add"] +attachment = ["attachment-download"] +attachment-command = [] +attachment-download = ["attachment-command", "message-read"] +template = ["template-write", "template-reply", "template-forward", "template-save", "template-send"] +template-command = [] +template-write = ["template-command"] +template-reply = ["template-command", "email-lib/message-get"] +template-forward = ["template-command", "email-lib/message-get"] +template-save = ["template-command", "email-lib/message-add"] +template-send = ["template-command", "email-lib/message-send"] +sync = ["account-command", "email-lib/sync"] pgp = [] -pgp-commands = ["pgp", "mml-lib/pgp-commands", "email-lib/pgp-commands"] -pgp-gpg = ["pgp", "mml-lib/pgp-gpg", "email-lib/pgp-gpg"] -pgp-native = ["pgp", "mml-lib/pgp-native", "email-lib/pgp-native"] +pgp-commands = ["email-lib/pgp-commands", "mml-lib/pgp-commands", "pgp"] +pgp-gpg = ["email-lib/pgp-gpg", "mml-lib/pgp-gpg", "pgp"] +pgp-native = ["email-lib/pgp-native", "mml-lib/pgp-native", "pgp"] [dev-dependencies] async-trait = "0.1" @@ -50,7 +105,8 @@ clap_mangen = "0.2" console = "0.15.2" dialoguer = "0.10.2" dirs = "4.0" -email-lib = { version = "=0.19.5", default-features = false } +# email-lib = { version = "=0.19.6", default-features = false } +email-lib = { git = "https://git.sr.ht/~soywod/pimalaya", default-features = false } email_address = "0.2.4" env_logger = "0.8" erased-serde = "0.3" diff --git a/src/account/command/configure.rs b/src/account/command/configure.rs index a3b1184..cd272cf 100644 --- a/src/account/command/configure.rs +++ b/src/account/command/configure.rs @@ -4,16 +4,13 @@ use clap::Parser; use email::imap::config::ImapAuthConfig; #[cfg(feature = "smtp")] use email::smtp::config::SmtpAuthConfig; -use log::{debug, info, warn}; +use log::info; +#[cfg(any(feature = "imap", feature = "smtp"))] +use log::{debug, warn}; -use crate::{ - account::arg::name::AccountNameArg, - config::{ - wizard::{prompt_passwd, prompt_secret}, - TomlConfig, - }, - printer::Printer, -}; +#[cfg(any(feature = "imap", feature = "smtp"))] +use crate::config::wizard::{prompt_passwd, prompt_secret}; +use crate::{account::arg::name::AccountNameArg, config::TomlConfig, printer::Printer}; /// Configure an account. /// diff --git a/src/account/command/mod.rs b/src/account/command/mod.rs index 0161821..f01c491 100644 --- a/src/account/command/mod.rs +++ b/src/account/command/mod.rs @@ -1,5 +1,8 @@ +#[cfg(feature = "account-configure")] mod configure; +#[cfg(feature = "account-list")] mod list; +#[cfg(feature = "sync")] mod sync; use anyhow::Result; @@ -7,9 +10,12 @@ use clap::Subcommand; use crate::{config::TomlConfig, printer::Printer}; -use self::{ - configure::AccountConfigureCommand, list::AccountListCommand, sync::AccountSyncCommand, -}; +#[cfg(feature = "account-configure")] +use self::configure::AccountConfigureCommand; +#[cfg(feature = "account-list")] +use self::list::AccountListCommand; +#[cfg(feature = "sync")] +use self::sync::AccountSyncCommand; /// Manage accounts. /// @@ -18,21 +24,28 @@ use self::{ /// file. This subcommand allows you to manage them. #[derive(Debug, Subcommand)] pub enum AccountSubcommand { + #[cfg(feature = "account-configure")] #[command(alias = "cfg")] Configure(AccountConfigureCommand), + #[cfg(feature = "account-list")] #[command(alias = "lst")] List(AccountListCommand), + #[cfg(feature = "sync")] #[command(alias = "synchronize", alias = "synchronise")] Sync(AccountSyncCommand), } impl AccountSubcommand { + #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { + #[cfg(feature = "account-configure")] Self::Configure(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "account-list")] Self::List(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "sync")] Self::Sync(cmd) => cmd.execute(printer, config).await, } } diff --git a/src/account/config.rs b/src/account/config.rs index 5d0295c..2b53a1e 100644 --- a/src/account/config.rs +++ b/src/account/config.rs @@ -5,14 +5,16 @@ #[cfg(feature = "pgp")] use email::account::config::pgp::PgpConfig; +#[cfg(feature = "sync")] +use email::account::sync::config::SyncConfig; #[cfg(feature = "imap")] use email::imap::config::ImapConfig; +#[cfg(feature = "maildir")] +use email::maildir::config::MaildirConfig; +#[cfg(feature = "sendmail")] +use email::sendmail::config::SendmailConfig; #[cfg(feature = "smtp")] use email::smtp::config::SmtpConfig; -use email::{ - account::sync::config::SyncConfig, maildir::config::MaildirConfig, - sendmail::config::SendmailConfig, -}; use serde::{Deserialize, Serialize}; use std::{collections::HashSet, path::PathBuf}; @@ -33,6 +35,7 @@ pub struct TomlAccountConfig { pub downloads_dir: Option, pub backend: Option, + #[cfg(feature = "sync")] pub sync: Option, #[cfg(feature = "pgp")] pub pgp: Option, @@ -55,6 +58,7 @@ pub struct TomlAccountConfig { } impl TomlAccountConfig { + #[cfg(feature = "folder-add")] pub fn add_folder_kind(&self) -> Option<&BackendKind> { self.folder .as_ref() @@ -63,6 +67,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "folder-list")] pub fn list_folders_kind(&self) -> Option<&BackendKind> { self.folder .as_ref() @@ -71,6 +76,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "folder-expunge")] pub fn expunge_folder_kind(&self) -> Option<&BackendKind> { self.folder .as_ref() @@ -79,6 +85,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "folder-purge")] pub fn purge_folder_kind(&self) -> Option<&BackendKind> { self.folder .as_ref() @@ -87,6 +94,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "folder-delete")] pub fn delete_folder_kind(&self) -> Option<&BackendKind> { self.folder .as_ref() @@ -95,6 +103,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "envelope-get")] pub fn get_envelope_kind(&self) -> Option<&BackendKind> { self.envelope .as_ref() @@ -103,6 +112,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "envelope-list")] pub fn list_envelopes_kind(&self) -> Option<&BackendKind> { self.envelope .as_ref() @@ -111,6 +121,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "envelope-watch")] pub fn watch_envelopes_kind(&self) -> Option<&BackendKind> { self.envelope .as_ref() @@ -119,6 +130,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "flag-add")] pub fn add_flags_kind(&self) -> Option<&BackendKind> { self.flag .as_ref() @@ -127,6 +139,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "flag-set")] pub fn set_flags_kind(&self) -> Option<&BackendKind> { self.flag .as_ref() @@ -135,6 +148,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "flag-remove")] pub fn remove_flags_kind(&self) -> Option<&BackendKind> { self.flag .as_ref() @@ -143,7 +157,8 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } - pub fn add_raw_message_kind(&self) -> Option<&BackendKind> { + #[cfg(feature = "message-add")] + pub fn add_message_kind(&self) -> Option<&BackendKind> { self.message .as_ref() .and_then(|msg| msg.write.as_ref()) @@ -151,6 +166,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "message-peek")] pub fn peek_messages_kind(&self) -> Option<&BackendKind> { self.message .as_ref() @@ -159,6 +175,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "message-get")] pub fn get_messages_kind(&self) -> Option<&BackendKind> { self.message .as_ref() @@ -167,6 +184,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "message-copy")] pub fn copy_messages_kind(&self) -> Option<&BackendKind> { self.message .as_ref() @@ -175,6 +193,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "message-move")] pub fn move_messages_kind(&self) -> Option<&BackendKind> { self.message .as_ref() @@ -183,6 +202,7 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } + #[cfg(feature = "message-delete")] pub fn delete_messages_kind(&self) -> Option<&BackendKind> { self.flag .as_ref() @@ -191,7 +211,8 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } - pub fn send_raw_message_kind(&self) -> Option<&BackendKind> { + #[cfg(any(feature = "message-send", feature = "template-send"))] + pub fn send_message_kind(&self) -> Option<&BackendKind> { self.message .as_ref() .and_then(|msg| msg.send.as_ref()) @@ -199,14 +220,6 @@ impl TomlAccountConfig { .or_else(|| self.backend.as_ref()) } - pub fn get_watch_message_kind(&self) -> Option<&BackendKind> { - self.envelope - .as_ref() - .and_then(|envelope| envelope.watch.as_ref()) - .and_then(|watch| watch.backend.as_ref()) - .or_else(|| self.backend.as_ref()) - } - pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut used_backends = HashSet::default(); @@ -218,14 +231,17 @@ impl TomlAccountConfig { used_backends.extend(folder.get_used_backends()); } + #[cfg(feature = "envelope-command")] if let Some(ref envelope) = self.envelope { used_backends.extend(envelope.get_used_backends()); } + #[cfg(feature = "flag-command")] if let Some(ref flag) = self.flag { used_backends.extend(flag.get_used_backends()); } + #[cfg(feature = "message-command")] if let Some(ref msg) = self.message { used_backends.extend(msg.get_used_backends()); } diff --git a/src/account/mod.rs b/src/account/mod.rs index 0817f99..62bed18 100644 --- a/src/account/mod.rs +++ b/src/account/mod.rs @@ -83,6 +83,7 @@ impl From> for Accounts { fn from(map: Iter<'_, String, TomlAccountConfig>) -> Self { let mut accounts: Vec<_> = map .map(|(name, account)| { + #[allow(unused_mut)] let mut backends = String::new(); #[cfg(feature = "imap")] @@ -90,6 +91,7 @@ impl From> for Accounts { backends.push_str("imap"); } + #[cfg(feature = "maildir")] if account.maildir.is_some() { if !backends.is_empty() { backends.push_str(", ") diff --git a/src/account/wizard.rs b/src/account/wizard.rs index aff4bf4..359f86a 100644 --- a/src/account/wizard.rs +++ b/src/account/wizard.rs @@ -1,13 +1,19 @@ use anyhow::{bail, Result}; -use dialoguer::{Confirm, Input}; +#[cfg(feature = "sync")] +use dialoguer::Confirm; +use dialoguer::Input; +#[cfg(feature = "sync")] use email::account::sync::config::SyncConfig; use email_address::EmailAddress; +#[cfg(feature = "message-send")] +use crate::message::config::{MessageConfig, MessageSendConfig}; +#[cfg(feature = "sync")] +use crate::wizard_prompt; +#[allow(unused)] use crate::{ backend::{self, config::BackendConfig, BackendKind}, config::wizard::THEME, - message::config::{MessageConfig, MessageSendConfig}, - wizard_prompt, }; use super::TomlAccountConfig; @@ -46,15 +52,16 @@ pub(crate) async fn configure() -> Result> { ); match backend::wizard::configure(&account_name, &config.email).await? { - Some(BackendConfig::Maildir(mdir_config)) => { - config.maildir = Some(mdir_config); - config.backend = Some(BackendKind::Maildir); - } #[cfg(feature = "imap")] Some(BackendConfig::Imap(imap_config)) => { config.imap = Some(imap_config); config.backend = Some(BackendKind::Imap); } + #[cfg(feature = "maildir")] + Some(BackendConfig::Maildir(mdir_config)) => { + config.maildir = Some(mdir_config); + config.backend = Some(BackendKind::Maildir); + } #[cfg(feature = "notmuch")] Some(BackendConfig::Notmuch(notmuch_config)) => { config.notmuch = Some(notmuch_config); @@ -64,43 +71,55 @@ pub(crate) async fn configure() -> Result> { }; match backend::wizard::configure_sender(&account_name, &config.email).await? { - Some(BackendConfig::Sendmail(sendmail_config)) => { - config.sendmail = Some(sendmail_config); - config.message = Some(MessageConfig { - send: Some(MessageSendConfig { - backend: Some(BackendKind::Sendmail), - ..Default::default() - }), - ..Default::default() - }); - } #[cfg(feature = "smtp")] Some(BackendConfig::Smtp(smtp_config)) => { config.smtp = Some(smtp_config); - config.message = Some(MessageConfig { - send: Some(MessageSendConfig { - backend: Some(BackendKind::Smtp), + + #[cfg(feature = "message-send")] + { + config.message = Some(MessageConfig { + send: Some(MessageSendConfig { + backend: Some(BackendKind::Smtp), + ..Default::default() + }), ..Default::default() - }), - ..Default::default() - }); + }); + } + } + #[cfg(feature = "sendmail")] + Some(BackendConfig::Sendmail(sendmail_config)) => { + config.sendmail = Some(sendmail_config); + + #[cfg(feature = "message-send")] + { + config.message = Some(MessageConfig { + send: Some(MessageSendConfig { + backend: Some(BackendKind::Sendmail), + ..Default::default() + }), + ..Default::default() + }); + } } _ => (), }; - let should_configure_sync = Confirm::new() - .with_prompt(wizard_prompt!( - "Do you need an offline access to your account?" - )) - .default(false) - .interact_opt()? - .unwrap_or_default(); + #[cfg(feature = "sync")] + { + let should_configure_sync = Confirm::new() + .with_prompt(wizard_prompt!( + "Do you need an offline access to your account?" + )) + .default(false) + .interact_opt()? + .unwrap_or_default(); - if should_configure_sync { - config.sync = Some(SyncConfig { - enable: Some(true), - ..Default::default() - }); + if should_configure_sync { + config.sync = Some(SyncConfig { + enable: Some(true), + ..Default::default() + }); + } } Ok(Some((account_name, config))) diff --git a/src/backend/config.rs b/src/backend/config.rs index 2284de3..dca3b14 100644 --- a/src/backend/config.rs +++ b/src/backend/config.rs @@ -1,19 +1,24 @@ #[cfg(feature = "imap")] use email::imap::config::ImapConfig; +#[cfg(feature = "maildir")] +use email::maildir::config::MaildirConfig; #[cfg(feature = "notmuch")] use email::notmuch::config::NotmuchConfig; +#[cfg(feature = "sendmail")] +use email::sendmail::config::SendmailConfig; #[cfg(feature = "smtp")] use email::smtp::config::SmtpConfig; -use email::{maildir::config::MaildirConfig, sendmail::config::SendmailConfig}; #[derive(Clone, Debug, Eq, PartialEq)] pub enum BackendConfig { - Maildir(MaildirConfig), #[cfg(feature = "imap")] Imap(ImapConfig), + #[cfg(feature = "maildir")] + Maildir(MaildirConfig), #[cfg(feature = "notmuch")] Notmuch(NotmuchConfig), #[cfg(feature = "smtp")] Smtp(SmtpConfig), + #[cfg(feature = "sendmail")] Sendmail(SendmailConfig), } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 60f1254..679151a 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -5,76 +5,128 @@ use anyhow::Result; use async_trait::async_trait; use std::ops::Deref; +use email::account::config::AccountConfig; +#[cfg(all(feature = "envelope-get", feature = "imap"))] +use email::envelope::get::imap::GetEnvelopeImap; +#[cfg(all(feature = "envelope-get", feature = "maildir"))] +use email::envelope::get::maildir::GetEnvelopeMaildir; +#[cfg(all(feature = "envelope-list", feature = "imap"))] +use email::envelope::list::imap::ListEnvelopesImap; +#[cfg(all(feature = "envelope-list", feature = "maildir"))] +use email::envelope::list::maildir::ListEnvelopesMaildir; +#[cfg(all(feature = "envelope-watch", feature = "imap"))] +use email::envelope::watch::imap::WatchImapEnvelopes; +#[cfg(all(feature = "envelope-watch", feature = "maildir"))] +use email::envelope::watch::maildir::WatchMaildirEnvelopes; +#[cfg(feature = "message-add")] +use email::envelope::SingleId; +#[cfg(all(feature = "flag-add", feature = "imap"))] +use email::flag::add::imap::AddFlagsImap; +#[cfg(all(feature = "flag-add", feature = "maildir"))] +use email::flag::add::maildir::AddFlagsMaildir; +#[cfg(all(feature = "flag-remove", feature = "imap"))] +use email::flag::remove::imap::RemoveFlagsImap; +#[cfg(all(feature = "flag-remove", feature = "maildir"))] +use email::flag::remove::maildir::RemoveFlagsMaildir; +#[cfg(all(feature = "flag-set", feature = "imap"))] +use email::flag::set::imap::SetFlagsImap; +#[cfg(all(feature = "flag-set", feature = "maildir"))] +use email::flag::set::maildir::SetFlagsMaildir; +#[cfg(all(feature = "folder-add", feature = "imap"))] +use email::folder::add::imap::AddFolderImap; +#[cfg(all(feature = "folder-add", feature = "maildir"))] +use email::folder::add::maildir::AddFolderMaildir; +#[cfg(all(feature = "folder-delete", feature = "imap"))] +use email::folder::delete::imap::DeleteFolderImap; +#[cfg(all(feature = "folder-delete", feature = "maildir"))] +use email::folder::delete::maildir::DeleteFolderMaildir; +#[cfg(all(feature = "folder-expunge", feature = "imap"))] +use email::folder::expunge::imap::ExpungeFolderImap; +#[cfg(all(feature = "folder-expunge", feature = "maildir"))] +use email::folder::expunge::maildir::ExpungeFolderMaildir; +#[cfg(all(feature = "folder-list", feature = "imap"))] +use email::folder::list::imap::ListFoldersImap; +#[cfg(all(feature = "folder-list", feature = "maildir"))] +use email::folder::list::maildir::ListFoldersMaildir; +#[cfg(all(feature = "folder-purge", feature = "imap"))] +use email::folder::purge::imap::PurgeFolderImap; #[cfg(feature = "imap")] use email::imap::{ImapSessionBuilder, ImapSessionSync}; +#[cfg(feature = "sync")] +use email::maildir::config::MaildirConfig; +#[cfg(feature = "maildir")] +use email::maildir::{MaildirSessionBuilder, MaildirSessionSync}; +#[cfg(all(feature = "message-add", feature = "maildir"))] +use email::message::add_with_flags::maildir::AddMessageWithFlagsMaildir; +#[cfg(all(feature = "message-copy", feature = "imap"))] +use email::message::copy::imap::CopyMessagesImap; +#[cfg(all(feature = "message-copy", feature = "maildir"))] +use email::message::copy::maildir::CopyMessagesMaildir; +#[cfg(all(feature = "message-get", feature = "imap"))] +use email::message::get::imap::GetMessagesImap; +#[cfg(all(feature = "message-move", feature = "imap"))] +use email::message::move_::imap::MoveMessagesImap; +#[cfg(all(feature = "message-move", feature = "maildir"))] +use email::message::move_::maildir::MoveMessagesMaildir; +#[cfg(all(feature = "message-peek", feature = "imap"))] +use email::message::peek::imap::PeekMessagesImap; +#[cfg(all(feature = "message-peek", feature = "maildir"))] +use email::message::peek::maildir::PeekMessagesMaildir; +#[cfg(any(feature = "message-peek", feature = "message-get"))] +use email::message::Messages; +#[cfg(all(feature = "message-add", feature = "imap"))] +use email::message::{add::imap::AddMessageImap, add_with_flags::imap::AddMessageWithFlagsImap}; +#[cfg(feature = "sendmail")] +use email::sendmail::SendmailContext; #[cfg(feature = "smtp")] use email::smtp::{SmtpClientBuilder, SmtpClientSync}; + +#[cfg(any(feature = "flag-command"))] use email::{ - account::config::AccountConfig, - envelope::{ - get::{imap::GetEnvelopeImap, maildir::GetEnvelopeMaildir}, - list::{imap::ListEnvelopesImap, maildir::ListEnvelopesMaildir}, - watch::{imap::WatchImapEnvelopes, maildir::WatchMaildirEnvelopes}, - Id, SingleId, - }, - flag::{ - add::{imap::AddFlagsImap, maildir::AddFlagsMaildir}, - remove::{imap::RemoveFlagsImap, maildir::RemoveFlagsMaildir}, - set::{imap::SetFlagsImap, maildir::SetFlagsMaildir}, - Flag, Flags, - }, - folder::{ - add::{imap::AddFolderImap, maildir::AddFolderMaildir}, - delete::{imap::DeleteFolderImap, maildir::DeleteFolderMaildir}, - expunge::{imap::ExpungeFolderImap, maildir::ExpungeFolderMaildir}, - list::{imap::ListFoldersImap, maildir::ListFoldersMaildir}, - purge::imap::PurgeFolderImap, - }, - maildir::{config::MaildirConfig, MaildirSessionBuilder, MaildirSessionSync}, - message::{ - add_raw::imap::AddRawMessageImap, - add_raw_with_flags::{ - imap::AddRawMessageWithFlagsImap, maildir::AddRawMessageWithFlagsMaildir, - }, - copy::{imap::CopyMessagesImap, maildir::CopyMessagesMaildir}, - get::imap::GetMessagesImap, - move_::{imap::MoveMessagesImap, maildir::MoveMessagesMaildir}, - peek::{imap::PeekMessagesImap, maildir::PeekMessagesMaildir}, - Messages, - }, - sendmail::SendmailContext, + envelope::Id, + flag::{Flag, Flags}, }; use serde::{Deserialize, Serialize}; -use crate::{account::config::TomlAccountConfig, cache::IdMapper, envelope::Envelopes}; +#[cfg(feature = "envelope-list")] +use crate::envelope::Envelopes; +use crate::{account::config::TomlAccountConfig, cache::IdMapper}; #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum BackendKind { - Maildir, - #[serde(skip_deserializing)] - MaildirForSync, #[cfg(feature = "imap")] Imap, + #[cfg(feature = "maildir")] + Maildir, + #[cfg(feature = "sync")] + #[serde(skip_deserializing)] + MaildirForSync, #[cfg(feature = "notmuch")] Notmuch, #[cfg(feature = "smtp")] Smtp, + #[cfg(feature = "sendmail")] Sendmail, + None, } impl ToString for BackendKind { fn to_string(&self) -> String { let kind = match self { - Self::Maildir => "Maildir", - Self::MaildirForSync => "Maildir", #[cfg(feature = "imap")] Self::Imap => "IMAP", + #[cfg(feature = "maildir")] + Self::Maildir => "Maildir", + #[cfg(feature = "sync")] + Self::MaildirForSync => "Maildir", #[cfg(feature = "notmuch")] Self::Notmuch => "Notmuch", #[cfg(feature = "smtp")] Self::Smtp => "SMTP", + #[cfg(feature = "sendmail")] Self::Sendmail => "Sendmail", + Self::None => "None", }; kind.to_string() @@ -83,34 +135,26 @@ impl ToString for BackendKind { #[derive(Clone, Default)] pub struct BackendContextBuilder { - pub maildir: Option, - pub maildir_for_sync: Option, #[cfg(feature = "imap")] pub imap: Option, + #[cfg(feature = "maildir")] + pub maildir: Option, + #[cfg(feature = "sync")] + pub maildir_for_sync: Option, #[cfg(feature = "smtp")] pub smtp: Option, + #[cfg(feature = "sendmail")] pub sendmail: Option, } impl BackendContextBuilder { + #[allow(unused)] pub async fn new( toml_account_config: &TomlAccountConfig, account_config: &AccountConfig, kinds: Vec<&BackendKind>, ) -> Result { Ok(Self { - maildir: toml_account_config - .maildir - .as_ref() - .filter(|_| kinds.contains(&&BackendKind::Maildir)) - .map(|mdir_config| { - MaildirSessionBuilder::new(account_config.clone(), mdir_config.clone()) - }), - maildir_for_sync: Some(MaildirConfig { - root_dir: account_config.get_sync_dir()?, - }) - .filter(|_| kinds.contains(&&BackendKind::MaildirForSync)) - .map(|mdir_config| MaildirSessionBuilder::new(account_config.clone(), mdir_config)), #[cfg(feature = "imap")] imap: { let ctx_builder = toml_account_config @@ -126,6 +170,20 @@ impl BackendContextBuilder { None => None, } }, + #[cfg(feature = "maildir")] + maildir: toml_account_config + .maildir + .as_ref() + .filter(|_| kinds.contains(&&BackendKind::Maildir)) + .map(|mdir_config| { + MaildirSessionBuilder::new(account_config.clone(), mdir_config.clone()) + }), + #[cfg(feature = "sync")] + maildir_for_sync: Some(MaildirConfig { + root_dir: account_config.get_sync_dir()?, + }) + .filter(|_| kinds.contains(&&BackendKind::MaildirForSync)) + .map(|mdir_config| MaildirSessionBuilder::new(account_config.clone(), mdir_config)), #[cfg(feature = "notmuch")] notmuch: toml_account_config .notmuch @@ -159,21 +217,24 @@ impl email::backend::BackendContextBuilder for BackendContextBuilder { type Context = BackendContext; async fn build(self) -> Result { + #[allow(unused_mut)] let mut ctx = BackendContext::default(); - if let Some(maildir) = self.maildir { - ctx.maildir = Some(maildir.build().await?); - } - - if let Some(maildir) = self.maildir_for_sync { - ctx.maildir_for_sync = Some(maildir.build().await?); - } - #[cfg(feature = "imap")] if let Some(imap) = self.imap { ctx.imap = Some(imap.build().await?); } + #[cfg(feature = "maildir")] + if let Some(maildir) = self.maildir { + ctx.maildir = Some(maildir.build().await?); + } + + #[cfg(feature = "sync")] + if let Some(maildir) = self.maildir_for_sync { + ctx.maildir_for_sync = Some(maildir.build().await?); + } + #[cfg(feature = "notmuch")] if let Some(notmuch) = self.notmuch { ctx.notmuch = Some(notmuch.build().await?); @@ -184,6 +245,7 @@ impl email::backend::BackendContextBuilder for BackendContextBuilder { ctx.smtp = Some(smtp.build().await?); } + #[cfg(feature = "sendmail")] if let Some(sendmail) = self.sendmail { ctx.sendmail = Some(sendmail.build().await?); } @@ -194,12 +256,15 @@ impl email::backend::BackendContextBuilder for BackendContextBuilder { #[derive(Default)] pub struct BackendContext { - pub maildir: Option, - pub maildir_for_sync: Option, #[cfg(feature = "imap")] pub imap: Option, + #[cfg(feature = "maildir")] + pub maildir: Option, + #[cfg(feature = "sync")] + pub maildir_for_sync: Option, #[cfg(feature = "smtp")] pub smtp: Option, + #[cfg(feature = "sendmail")] pub sendmail: Option, } @@ -213,27 +278,17 @@ impl BackendBuilder { toml_account_config: TomlAccountConfig, account_config: AccountConfig, ) -> Result { + #[allow(unused)] 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")] let is_imap_used = used_backends.contains(&BackendKind::Imap); + #[cfg(feature = "maildir")] + let is_maildir_used = used_backends.contains(&BackendKind::Maildir); + #[cfg(feature = "sync")] + let is_maildir_for_sync_used = used_backends.contains(&BackendKind::MaildirForSync); let backend_ctx_builder = BackendContextBuilder { - 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.get_sync_dir()?, - }) - .filter(|_| is_maildir_for_sync_used) - .map(|mdir_config| MaildirSessionBuilder::new(account_config.clone(), mdir_config)), - #[cfg(feature = "imap")] imap: { let ctx_builder = toml_account_config @@ -250,17 +305,35 @@ impl BackendBuilder { None => None, } }, + #[cfg(feature = "maildir")] + maildir: toml_account_config + .maildir + .as_ref() + .filter(|_| is_maildir_used) + .map(|mdir_config| { + MaildirSessionBuilder::new(account_config.clone(), mdir_config.clone()) + }), + #[cfg(feature = "sync")] + maildir_for_sync: Some(MaildirConfig { + root_dir: account_config.get_sync_dir()?, + }) + .filter(|_| is_maildir_for_sync_used) + .map(|mdir_config| MaildirSessionBuilder::new(account_config.clone(), mdir_config)), ..Default::default() }; + #[allow(unused_mut)] let mut backend_builder = email::backend::BackendBuilder::new(account_config.clone(), backend_ctx_builder); + #[cfg(feature = "folder-add")] match toml_account_config.add_folder_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder .with_add_folder(|ctx| ctx.maildir.as_ref().and_then(AddFolderMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_add_folder(|ctx| { ctx.maildir_for_sync @@ -281,12 +354,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "folder-list")] match toml_account_config.list_folders_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_list_folders(|ctx| { ctx.maildir.as_ref().and_then(ListFoldersMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_list_folders(|ctx| { ctx.maildir_for_sync @@ -308,12 +384,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "folder-expunge")] match toml_account_config.expunge_folder_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_expunge_folder(|ctx| { ctx.maildir.as_ref().and_then(ExpungeFolderMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_expunge_folder(|ctx| { ctx.maildir_for_sync @@ -335,13 +414,16 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "folder-purge")] match toml_account_config.purge_folder_kind() { // TODO + // #[cfg(feature = "maildir")] // Some(BackendKind::Maildir) => { // backend_builder = backend_builder // .with_purge_folder(|ctx| ctx.maildir.as_ref().and_then(PurgeFolderMaildir::new)); // } // TODO + // #[cfg(feature = "sync")] // Some(BackendKind::MaildirForSync) => { // backend_builder = backend_builder // .with_purge_folder(|ctx| ctx.maildir_for_sync.as_ref().and_then(PurgeFolderMaildir::new)); @@ -360,12 +442,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "folder-delete")] match toml_account_config.delete_folder_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_delete_folder(|ctx| { ctx.maildir.as_ref().and_then(DeleteFolderMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_delete_folder(|ctx| { ctx.maildir_for_sync @@ -387,12 +472,45 @@ impl BackendBuilder { _ => (), } - match toml_account_config.backend { + #[cfg(feature = "envelope-list")] + match toml_account_config.list_envelopes_kind() { + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + backend_builder = backend_builder.with_list_envelopes(|ctx| { + ctx.maildir.as_ref().and_then(ListEnvelopesMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + backend_builder = backend_builder.with_list_envelopes(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(ListEnvelopesMaildir::new) + }); + } + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + backend_builder = backend_builder + .with_list_envelopes(|ctx| ctx.imap.as_ref().and_then(ListEnvelopesImap::new)); + } + #[cfg(feature = "notmuch")] + Some(BackendKind::Notmuch) => { + backend_builder = backend_builder.with_list_envelopes(|ctx| { + ctx.notmuch.as_ref().and_then(ListEnvelopesNotmuch::new) + }); + } + _ => (), + } + + #[cfg(feature = "envelope-watch")] + match toml_account_config.watch_envelopes_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_watch_envelopes(|ctx| { ctx.maildir.as_ref().and_then(WatchMaildirEnvelopes::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_watch_envelopes(|ctx| { ctx.maildir_for_sync @@ -415,12 +533,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "envelope-get")] match toml_account_config.get_envelope_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_get_envelope(|ctx| { ctx.maildir.as_ref().and_then(GetEnvelopeMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_get_envelope(|ctx| { ctx.maildir_for_sync @@ -442,38 +563,14 @@ impl BackendBuilder { _ => (), } - match toml_account_config.list_envelopes_kind() { - Some(BackendKind::Maildir) => { - backend_builder = backend_builder.with_list_envelopes(|ctx| { - ctx.maildir.as_ref().and_then(ListEnvelopesMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - backend_builder = backend_builder.with_list_envelopes(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(ListEnvelopesMaildir::new) - }); - } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - backend_builder = backend_builder - .with_list_envelopes(|ctx| ctx.imap.as_ref().and_then(ListEnvelopesImap::new)); - } - #[cfg(feature = "notmuch")] - Some(BackendKind::Notmuch) => { - backend_builder = backend_builder.with_list_envelopes(|ctx| { - ctx.notmuch.as_ref().and_then(ListEnvelopesNotmuch::new) - }); - } - _ => (), - } - + #[cfg(feature = "flag-add")] match toml_account_config.add_flags_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder .with_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_add_flags(|ctx| { ctx.maildir_for_sync.as_ref().and_then(AddFlagsMaildir::new) @@ -492,11 +589,14 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "flag-set")] match toml_account_config.set_flags_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder .with_set_flags(|ctx| ctx.maildir.as_ref().and_then(SetFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_set_flags(|ctx| { ctx.maildir_for_sync.as_ref().and_then(SetFlagsMaildir::new) @@ -515,12 +615,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "flag-remove")] match toml_account_config.remove_flags_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_remove_flags(|ctx| { ctx.maildir.as_ref().and_then(RemoveFlagsMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_remove_flags(|ctx| { ctx.maildir_for_sync @@ -542,29 +645,32 @@ impl BackendBuilder { _ => (), } - match toml_account_config.add_raw_message_kind() { - Some(BackendKind::Maildir) => { - backend_builder = backend_builder.with_add_raw_message_with_flags(|ctx| { - ctx.maildir - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - backend_builder = backend_builder.with_add_raw_message_with_flags(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } + #[cfg(feature = "message-add")] + match toml_account_config.add_message_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => { backend_builder = backend_builder - .with_add_raw_message(|ctx| ctx.imap.as_ref().and_then(AddRawMessageImap::new)) - .with_add_raw_message_with_flags(|ctx| { - ctx.imap.as_ref().and_then(AddRawMessageWithFlagsImap::new) + .with_add_message(|ctx| ctx.imap.as_ref().and_then(AddMessageImap::new)) + .with_add_message_with_flags(|ctx| { + ctx.imap.as_ref().and_then(AddMessageWithFlagsImap::new) }); } + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + backend_builder = backend_builder.with_add_message_with_flags(|ctx| { + ctx.maildir + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + backend_builder = backend_builder.with_add_message_with_flags(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } #[cfg(feature = "notmuch")] Some(BackendKind::Notmuch) => { backend_builder = backend_builder.with_add_raw_message(|ctx| { @@ -574,12 +680,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "message-peek")] match toml_account_config.peek_messages_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_peek_messages(|ctx| { ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_peek_messages(|ctx| { ctx.maildir_for_sync @@ -601,6 +710,7 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "message-get")] match toml_account_config.get_messages_kind() { #[cfg(feature = "imap")] Some(BackendKind::Imap) => { @@ -616,12 +726,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "message-copy")] match toml_account_config.copy_messages_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_copy_messages(|ctx| { ctx.maildir.as_ref().and_then(CopyMessagesMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_copy_messages(|ctx| { ctx.maildir_for_sync @@ -643,12 +756,15 @@ impl BackendBuilder { _ => (), } + #[cfg(feature = "message-move")] match toml_account_config.move_messages_kind() { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { backend_builder = backend_builder.with_move_messages(|ctx| { ctx.maildir.as_ref().and_then(MoveMessagesMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { backend_builder = backend_builder.with_move_messages(|ctx| { ctx.maildir_for_sync @@ -699,6 +815,7 @@ impl Into> for BackendBuil } pub struct Backend { + #[allow(unused)] toml_account_config: TomlAccountConfig, backend: email::backend::Backend, } @@ -724,14 +841,17 @@ impl Backend { }) } + #[allow(unused)] fn build_id_mapper( &self, folder: &str, backend_kind: Option<&BackendKind>, ) -> Result { + #[allow(unused_mut)] let mut id_mapper = IdMapper::Dummy; match backend_kind { + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { if let Some(mdir_config) = &self.toml_account_config.maildir { id_mapper = IdMapper::new( @@ -741,6 +861,7 @@ impl Backend { )?; } } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { id_mapper = IdMapper::new( &self.backend.account_config, @@ -764,6 +885,7 @@ impl Backend { Ok(id_mapper) } + #[cfg(feature = "envelope-list")] pub async fn list_envelopes( &self, folder: &str, @@ -777,6 +899,7 @@ impl Backend { Ok(envelopes) } + #[cfg(feature = "flag-add")] pub async fn add_flags(&self, folder: &str, ids: &[usize], flags: &Flags) -> Result<()> { let backend_kind = self.toml_account_config.add_flags_kind(); let id_mapper = self.build_id_mapper(folder, backend_kind)?; @@ -784,6 +907,15 @@ impl Backend { self.backend.add_flags(folder, &ids, flags).await } + #[cfg(feature = "flag-add")] + pub async fn add_flag(&self, folder: &str, ids: &[usize], flag: Flag) -> 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_flag(folder, &ids, flag).await + } + + #[cfg(feature = "flag-set")] pub async fn set_flags(&self, folder: &str, ids: &[usize], flags: &Flags) -> Result<()> { let backend_kind = self.toml_account_config.set_flags_kind(); let id_mapper = self.build_id_mapper(folder, backend_kind)?; @@ -791,6 +923,15 @@ impl Backend { self.backend.set_flags(folder, &ids, flags).await } + #[cfg(feature = "flag-set")] + pub async fn set_flag(&self, folder: &str, ids: &[usize], flag: Flag) -> 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_flag(folder, &ids, flag).await + } + + #[cfg(feature = "flag-remove")] pub async fn remove_flags(&self, folder: &str, ids: &[usize], flags: &Flags) -> Result<()> { let backend_kind = self.toml_account_config.remove_flags_kind(); let id_mapper = self.build_id_mapper(folder, backend_kind)?; @@ -798,6 +939,24 @@ impl Backend { self.backend.remove_flags(folder, &ids, flags).await } + #[cfg(feature = "flag-remove")] + pub async fn remove_flag(&self, folder: &str, ids: &[usize], flag: Flag) -> 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_flag(folder, &ids, flag).await + } + + #[cfg(feature = "message-add")] + pub async fn add_message(&self, folder: &str, email: &[u8]) -> Result { + let backend_kind = self.toml_account_config.add_message_kind(); + let id_mapper = self.build_id_mapper(folder, backend_kind)?; + let id = self.backend.add_message(folder, email).await?; + id_mapper.create_alias(&*id)?; + Ok(id) + } + + #[cfg(feature = "message-peek")] pub async fn peek_messages(&self, folder: &str, ids: &[usize]) -> Result { let backend_kind = self.toml_account_config.get_messages_kind(); let id_mapper = self.build_id_mapper(folder, backend_kind)?; @@ -805,6 +964,7 @@ impl Backend { self.backend.peek_messages(folder, &ids).await } + #[cfg(feature = "message-get")] pub async fn get_messages(&self, folder: &str, ids: &[usize]) -> Result { let backend_kind = self.toml_account_config.get_messages_kind(); let id_mapper = self.build_id_mapper(folder, backend_kind)?; @@ -812,6 +972,7 @@ impl Backend { self.backend.get_messages(folder, &ids).await } + #[cfg(feature = "message-copy")] pub async fn copy_messages( &self, from_folder: &str, @@ -826,6 +987,7 @@ impl Backend { .await } + #[cfg(feature = "message-move")] pub async fn move_messages( &self, from_folder: &str, @@ -840,41 +1002,13 @@ impl Backend { .await } + #[cfg(feature = "message-delete")] pub async fn delete_messages(&self, folder: &str, ids: &[usize]) -> 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) - } - - pub async fn add_flag(&self, folder: &str, ids: &[usize], flag: Flag) -> 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_flag(folder, &ids, flag).await - } - - pub async fn set_flag(&self, folder: &str, ids: &[usize], flag: Flag) -> 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_flag(folder, &ids, flag).await - } - - pub async fn remove_flag(&self, folder: &str, ids: &[usize], flag: Flag) -> 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_flag(folder, &ids, flag).await - } } impl Deref for Backend { diff --git a/src/backend/wizard.rs b/src/backend/wizard.rs index 475dcbf..58fcd90 100644 --- a/src/backend/wizard.rs +++ b/src/backend/wizard.rs @@ -1,19 +1,24 @@ use anyhow::Result; use dialoguer::Select; +use crate::config::wizard::THEME; #[cfg(feature = "imap")] use crate::imap; +#[cfg(feature = "maildir")] +use crate::maildir; #[cfg(feature = "notmuch")] use crate::notmuch; +#[cfg(feature = "sendmail")] +use crate::sendmail; #[cfg(feature = "smtp")] use crate::smtp; -use crate::{config::wizard::THEME, maildir, sendmail}; use super::{config::BackendConfig, BackendKind}; const DEFAULT_BACKEND_KINDS: &[BackendKind] = &[ #[cfg(feature = "imap")] BackendKind::Imap, + #[cfg(feature = "maildir")] BackendKind::Maildir, #[cfg(feature = "notmuch")] BackendKind::Notmuch, @@ -22,10 +27,14 @@ const DEFAULT_BACKEND_KINDS: &[BackendKind] = &[ const SEND_MESSAGE_BACKEND_KINDS: &[BackendKind] = &[ #[cfg(feature = "smtp")] BackendKind::Smtp, + #[cfg(feature = "sendmail")] BackendKind::Sendmail, ]; -pub(crate) async fn configure(account_name: &str, email: &str) -> Result> { +pub(crate) async fn configure( + #[allow(unused)] account_name: &str, + #[allow(unused)] email: &str, +) -> Result> { let kind = Select::with_theme(&*THEME) .with_prompt("Default email backend") .items(DEFAULT_BACKEND_KINDS) @@ -34,11 +43,12 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result Some(maildir::wizard::configure()?), #[cfg(feature = "imap")] Some(kind) if kind == BackendKind::Imap => { Some(imap::wizard::configure(account_name, email).await?) } + #[cfg(feature = "maildir")] + Some(kind) if kind == BackendKind::Maildir => Some(maildir::wizard::configure()?), #[cfg(feature = "notmuch")] Some(kind) if kind == BackendKind::Notmuch => Some(notmuch::wizard::configure()?), _ => None, @@ -48,8 +58,8 @@ pub(crate) async fn configure(account_name: &str, email: &str) -> Result Result> { let kind = Select::with_theme(&*THEME) .with_prompt("Backend for sending messages") @@ -59,11 +69,12 @@ pub(crate) async fn configure_sender( .and_then(|idx| SEND_MESSAGE_BACKEND_KINDS.get(idx).map(Clone::clone)); let config = match kind { - Some(kind) if kind == BackendKind::Sendmail => Some(sendmail::wizard::configure()?), #[cfg(feature = "smtp")] Some(kind) if kind == BackendKind::Smtp => { Some(smtp::wizard::configure(account_name, email).await?) } + #[cfg(feature = "sendmail")] + Some(kind) if kind == BackendKind::Sendmail => Some(sendmail::wizard::configure()?), _ => None, }; diff --git a/src/cli.rs b/src/cli.rs index 0ebc5f8..4e00a98 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,18 +2,25 @@ use anyhow::Result; use clap::{Parser, Subcommand}; use std::path::PathBuf; +#[cfg(feature = "account-command")] +use crate::account::command::AccountSubcommand; +#[cfg(feature = "envelope-command")] +use crate::envelope::command::EnvelopeSubcommand; +#[cfg(feature = "flag-command")] +use crate::flag::command::FlagSubcommand; +#[cfg(feature = "folder-command")] +use crate::folder::command::FolderSubcommand; +#[cfg(feature = "attachment-command")] +use crate::message::attachment::command::AttachmentSubcommand; +#[cfg(feature = "message-command")] +use crate::message::command::MessageSubcommand; +#[cfg(feature = "template-command")] +use crate::message::template::command::TemplateSubcommand; +#[allow(unused)] use crate::{ - account::command::AccountSubcommand, completion::command::CompletionGenerateCommand, config::{self, TomlConfig}, - envelope::command::EnvelopeSubcommand, - flag::command::FlagSubcommand, - folder::command::FolderSubcommand, manual::command::ManualGenerateCommand, - message::{ - attachment::command::AttachmentSubcommand, command::MessageSubcommand, - template::command::TemplateSubcommand, - }, output::{ColorFmt, OutputFmt}, printer::Printer, }; @@ -22,8 +29,12 @@ use crate::{ #[command(name = "himalaya", author, version, about)] #[command(propagate_version = true, infer_subcommands = true)] pub struct Cli { + #[cfg(feature = "envelope-list")] #[command(subcommand)] pub command: Option, + #[cfg(not(feature = "envelope-list"))] + #[command(subcommand)] + pub command: HimalayaCommand, /// Override the default configuration file path /// @@ -77,31 +88,38 @@ pub struct Cli { #[derive(Subcommand, Debug)] pub enum HimalayaCommand { + #[cfg(feature = "account-command")] #[command(subcommand)] #[command(alias = "accounts")] Account(AccountSubcommand), + #[cfg(feature = "folder-command")] #[command(subcommand)] #[command(visible_alias = "mailbox", aliases = ["mailboxes", "mboxes", "mbox"])] #[command(alias = "folders")] Folder(FolderSubcommand), + #[cfg(feature = "envelope-command")] #[command(subcommand)] #[command(alias = "envelopes")] Envelope(EnvelopeSubcommand), + #[cfg(feature = "flag-command")] #[command(subcommand)] #[command(alias = "flags")] Flag(FlagSubcommand), + #[cfg(feature = "message-command")] #[command(subcommand)] #[command(alias = "messages", alias = "msgs", alias = "msg")] Message(MessageSubcommand), + #[cfg(feature = "attachment-command")] #[command(subcommand)] #[command(alias = "attachments")] Attachment(AttachmentSubcommand), + #[cfg(feature = "template-command")] #[command(subcommand)] #[command(alias = "templates", alias = "tpls", alias = "tpl")] Template(TemplateSubcommand), @@ -116,36 +134,44 @@ pub enum HimalayaCommand { } impl HimalayaCommand { + #[allow(unused)] pub async fn execute( self, printer: &mut impl Printer, config_path: Option<&PathBuf>, ) -> Result<()> { match self { + #[cfg(feature = "account-command")] Self::Account(cmd) => { let config = TomlConfig::from_some_path_or_default(config_path).await?; cmd.execute(printer, &config).await } + #[cfg(feature = "folder-command")] Self::Folder(cmd) => { let config = TomlConfig::from_some_path_or_default(config_path).await?; cmd.execute(printer, &config).await } + #[cfg(feature = "envelope-command")] Self::Envelope(cmd) => { let config = TomlConfig::from_some_path_or_default(config_path).await?; cmd.execute(printer, &config).await } + #[cfg(feature = "flag-command")] Self::Flag(cmd) => { let config = TomlConfig::from_some_path_or_default(config_path).await?; cmd.execute(printer, &config).await } + #[cfg(feature = "message-command")] Self::Message(cmd) => { let config = TomlConfig::from_some_path_or_default(config_path).await?; cmd.execute(printer, &config).await } + #[cfg(feature = "attachment-command")] Self::Attachment(cmd) => { let config = TomlConfig::from_some_path_or_default(config_path).await?; cmd.execute(printer, &config).await } + #[cfg(feature = "template-command")] Self::Template(cmd) => { let config = TomlConfig::from_some_path_or_default(config_path).await?; cmd.execute(printer, &config).await diff --git a/src/config/mod.rs b/src/config/mod.rs index 067e12f..26c28ba 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -8,6 +8,7 @@ use email::{ account::config::AccountConfig, config::Config, envelope::config::EnvelopeConfig, folder::config::FolderConfig, message::config::MessageConfig, }; + use serde::{Deserialize, Serialize}; use shellexpand_utils::{canonicalize, expand}; use std::{ @@ -18,7 +19,9 @@ use std::{ }; use toml; -use crate::{account::config::TomlAccountConfig, backend::BackendKind, wizard_prompt, wizard_warn}; +#[cfg(feature = "sync")] +use crate::backend::BackendKind; +use crate::{account::config::TomlAccountConfig, wizard_prompt, wizard_warn}; /// Represents the user config file. #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] @@ -132,6 +135,7 @@ impl TomlConfig { &self, account_name: Option<&str>, ) -> Result<(String, TomlAccountConfig)> { + #[allow(unused_mut)] let (account_name, mut toml_account_config) = match account_name { Some("default") | Some("") | None => self .accounts @@ -171,11 +175,13 @@ impl TomlConfig { pub fn into_account_configs( self, account_name: Option<&str>, - disable_cache: bool, + #[cfg(feature = "sync")] disable_cache: bool, ) -> Result<(TomlAccountConfig, AccountConfig)> { + #[cfg_attr(not(feature = "sync"), allow(unused_mut))] let (account_name, mut toml_account_config) = self.into_toml_account_config(account_name)?; + #[cfg(feature = "sync")] if let Some(true) = toml_account_config.sync.as_ref().and_then(|c| c.enable) { if !disable_cache { toml_account_config.backend = Some(BackendKind::MaildirForSync); @@ -200,19 +206,29 @@ impl TomlConfig { signature_delim: config.signature_delim, downloads_dir: config.downloads_dir, - folder: config.folder.map(|c| FolderConfig { + folder: config.folder.map(|#[allow(unused)] c| FolderConfig { aliases: c.alias, + #[cfg(feature = "folder-list")] list: c.list.map(|c| c.remote), + ..Default::default() }), - envelope: config.envelope.map(|c| EnvelopeConfig { + envelope: config.envelope.map(|#[allow(unused)] c| EnvelopeConfig { + #[cfg(feature = "envelope-list")] list: c.list.map(|c| c.remote), + #[cfg(feature = "envelope-watch")] watch: c.watch.map(|c| c.remote), + ..Default::default() }), - message: config.message.map(|c| MessageConfig { + message: config.message.map(|#[allow(unused)] c| MessageConfig { + #[cfg(feature = "message-read")] read: c.read.map(|c| c.remote), + #[cfg(feature = "message-write")] write: c.write.map(|c| c.remote), + #[cfg(feature = "message-send")] send: c.send.map(|c| c.remote), + ..Default::default() }), + #[cfg(feature = "sync")] sync: config.sync, #[cfg(feature = "pgp")] pgp: config.pgp, diff --git a/src/config/wizard.rs b/src/config/wizard.rs index e0f2a5c..866e71c 100644 --- a/src/config/wizard.rs +++ b/src/config/wizard.rs @@ -172,6 +172,7 @@ fn set_tables_dotted<'a>(item: &'a mut Item, keys: impl IntoIterator io::Result { Password::with_theme(&*THEME) .with_prompt(prompt) @@ -182,6 +183,7 @@ pub(crate) fn prompt_passwd(prompt: &str) -> io::Result { .interact() } +#[allow(unused)] pub(crate) fn prompt_secret(prompt: &str) -> io::Result { Password::with_theme(&*THEME) .with_prompt(prompt) diff --git a/src/email/envelope/command/list.rs b/src/email/envelope/command/list.rs index 4f2823b..52602eb 100644 --- a/src/email/envelope/command/list.rs +++ b/src/email/envelope/command/list.rs @@ -8,10 +8,11 @@ use email::envelope::list::maildir::ListEnvelopesMaildir; use email::envelope::list::notmuch::ListEnvelopesNotmuch; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, folder::arg::name::FolderNameOptionalArg, printer::{PrintTableOpts, Printer}, @@ -43,6 +44,7 @@ pub struct ListEnvelopesCommand { #[command(flatten)] pub table: TableMaxWidthFlag, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -57,6 +59,7 @@ impl Default for ListEnvelopesCommand { page: 1, page_size: Default::default(), table: Default::default(), + #[cfg(feature = "sync")] cache: Default::default(), account: Default::default(), } @@ -69,6 +72,7 @@ impl ListEnvelopesCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -85,11 +89,19 @@ impl ListEnvelopesCommand { &account_config, list_envelopes_kind, |builder| match list_envelopes_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder.set_list_envelopes(|ctx| { + ctx.imap.as_ref().and_then(ListEnvelopesImap::new) + }); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_list_envelopes(|ctx| { ctx.maildir.as_ref().and_then(ListEnvelopesMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_list_envelopes(|ctx| { ctx.maildir_for_sync @@ -97,12 +109,6 @@ impl ListEnvelopesCommand { .and_then(ListEnvelopesMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder.set_list_envelopes(|ctx| { - ctx.imap.as_ref().and_then(ListEnvelopesImap::new) - }); - } _ => (), }, ) diff --git a/src/email/envelope/command/mod.rs b/src/email/envelope/command/mod.rs index a97a2d2..e334eab 100644 --- a/src/email/envelope/command/mod.rs +++ b/src/email/envelope/command/mod.rs @@ -1,4 +1,6 @@ +#[cfg(feature = "envelope-list")] pub mod list; +#[cfg(feature = "envelope-watch")] pub mod watch; use anyhow::Result; @@ -6,7 +8,10 @@ use clap::Subcommand; use crate::{config::TomlConfig, printer::Printer}; -use self::{list::ListEnvelopesCommand, watch::WatchEnvelopesCommand}; +#[cfg(feature = "envelope-list")] +use self::list::ListEnvelopesCommand; +#[cfg(feature = "envelope-watch")] +use self::watch::WatchEnvelopesCommand; /// Manage envelopes. /// @@ -16,17 +21,22 @@ use self::{list::ListEnvelopesCommand, watch::WatchEnvelopesCommand}; /// manage them. #[derive(Debug, Subcommand)] pub enum EnvelopeSubcommand { + #[cfg(feature = "envelope-list")] #[command(alias = "lst")] List(ListEnvelopesCommand), + #[cfg(feature = "envelope-watch")] #[command()] Watch(WatchEnvelopesCommand), } impl EnvelopeSubcommand { + #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { + #[cfg(feature = "envelope-list")] Self::List(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "envelope-watch")] Self::Watch(cmd) => cmd.execute(printer, config).await, } } diff --git a/src/email/envelope/command/watch.rs b/src/email/envelope/command/watch.rs index 62bbba0..6e3a5f6 100644 --- a/src/email/envelope/command/watch.rs +++ b/src/email/envelope/command/watch.rs @@ -8,10 +8,11 @@ use email::envelope::watch::maildir::WatchMaildirEnvelopes; use email::envelope::watch::notmuch::WatchNotmuchEnvelopes; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, folder::arg::name::FolderNameOptionalFlag, printer::Printer, @@ -26,6 +27,7 @@ pub struct WatchEnvelopesCommand { #[command(flatten)] pub folder: FolderNameOptionalFlag, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -40,6 +42,7 @@ impl WatchEnvelopesCommand { let folder = &self.folder.name; let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -50,11 +53,19 @@ impl WatchEnvelopesCommand { &account_config, watch_envelopes_kind, |builder| match watch_envelopes_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder.set_watch_envelopes(|ctx| { + ctx.imap.as_ref().and_then(WatchImapEnvelopes::new) + }); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_watch_envelopes(|ctx| { ctx.maildir.as_ref().and_then(WatchMaildirEnvelopes::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_watch_envelopes(|ctx| { ctx.maildir_for_sync @@ -62,12 +73,6 @@ impl WatchEnvelopesCommand { .and_then(WatchMaildirEnvelopes::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder.set_watch_envelopes(|ctx| { - ctx.imap.as_ref().and_then(WatchImapEnvelopes::new) - }); - } _ => (), }, ) diff --git a/src/email/envelope/config.rs b/src/email/envelope/config.rs index c90d840..a17bea4 100644 --- a/src/email/envelope/config.rs +++ b/src/email/envelope/config.rs @@ -5,31 +5,39 @@ use crate::backend::BackendKind; #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct EnvelopeConfig { + #[cfg(feature = "envelope-list")] pub list: Option, + #[cfg(feature = "envelope-watch")] pub watch: Option, + #[cfg(feature = "envelope-get")] pub get: Option, } impl EnvelopeConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + #[allow(unused_mut)] let mut kinds = HashSet::default(); + #[cfg(feature = "envelope-list")] if let Some(list) = &self.list { kinds.extend(list.get_used_backends()); } - if let Some(get) = &self.get { - kinds.extend(get.get_used_backends()); - } - + #[cfg(feature = "envelope-watch")] if let Some(watch) = &self.watch { kinds.extend(watch.get_used_backends()); } + #[cfg(feature = "envelope-get")] + if let Some(get) = &self.get { + kinds.extend(get.get_used_backends()); + } + kinds } } +#[cfg(feature = "envelope-list")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct ListEnvelopesConfig { pub backend: Option, @@ -38,6 +46,7 @@ pub struct ListEnvelopesConfig { pub remote: email::envelope::list::config::EnvelopeListConfig, } +#[cfg(feature = "envelope-list")] impl ListEnvelopesConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -50,6 +59,7 @@ impl ListEnvelopesConfig { } } +#[cfg(feature = "envelope-watch")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct WatchEnvelopesConfig { pub backend: Option, @@ -58,6 +68,7 @@ pub struct WatchEnvelopesConfig { pub remote: email::envelope::watch::config::WatchEnvelopeConfig, } +#[cfg(feature = "envelope-watch")] impl WatchEnvelopesConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -70,11 +81,13 @@ impl WatchEnvelopesConfig { } } +#[cfg(feature = "envelope-get")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct GetEnvelopeConfig { pub backend: Option, } +#[cfg(feature = "envelope-get")] impl GetEnvelopeConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); diff --git a/src/email/envelope/flag/command/add.rs b/src/email/envelope/flag/command/add.rs index 55fc697..b5af90d 100644 --- a/src/email/envelope/flag/command/add.rs +++ b/src/email/envelope/flag/command/add.rs @@ -8,10 +8,11 @@ use email::flag::add::maildir::AddFlagsMaildir; use email::flag::add::notmuch::AddFlagsNotmuch; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs}, folder::arg::name::FolderNameOptionalFlag, @@ -30,6 +31,7 @@ pub struct FlagAddCommand { #[command(flatten)] pub args: IdsAndFlagsArgs, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -45,6 +47,7 @@ impl FlagAddCommand { let (ids, flags) = into_tuple(&self.args.ids_and_flags); let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -55,19 +58,21 @@ impl FlagAddCommand { &account_config, add_flags_kind, |builder| match add_flags_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder.set_add_flags(|ctx| ctx.imap.as_ref().and_then(AddFlagsImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder .set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_add_flags(|ctx| { ctx.maildir_for_sync.as_ref().and_then(AddFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder.set_add_flags(|ctx| ctx.imap.as_ref().and_then(AddFlagsImap::new)); - } _ => (), }, ) diff --git a/src/email/envelope/flag/command/mod.rs b/src/email/envelope/flag/command/mod.rs index 87d1633..ceb111e 100644 --- a/src/email/envelope/flag/command/mod.rs +++ b/src/email/envelope/flag/command/mod.rs @@ -1,5 +1,8 @@ +#[cfg(feature = "flag-add")] mod add; +#[cfg(feature = "flag-remove")] mod remove; +#[cfg(feature = "flag-set")] mod set; use anyhow::Result; @@ -7,7 +10,12 @@ use clap::Subcommand; use crate::{config::TomlConfig, printer::Printer}; -use self::{add::FlagAddCommand, remove::FlagRemoveCommand, set::FlagSetCommand}; +#[cfg(feature = "flag-add")] +use self::add::FlagAddCommand; +#[cfg(feature = "flag-remove")] +use self::remove::FlagRemoveCommand; +#[cfg(feature = "flag-set")] +use self::set::FlagSetCommand; /// Manage flags. /// @@ -17,24 +25,31 @@ use self::{add::FlagAddCommand, remove::FlagRemoveCommand, set::FlagSetCommand}; /// synchronization does not take care of them yet). #[derive(Debug, Subcommand)] pub enum FlagSubcommand { + #[cfg(feature = "flag-add")] #[command(arg_required_else_help = true)] #[command(alias = "create")] Add(FlagAddCommand), + #[cfg(feature = "flag-set")] #[command(arg_required_else_help = true)] #[command(aliases = ["update", "change", "replace"])] Set(FlagSetCommand), + #[cfg(feature = "flag-remove")] #[command(arg_required_else_help = true)] #[command(aliases = ["rm", "delete", "del"])] Remove(FlagRemoveCommand), } impl FlagSubcommand { + #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { + #[cfg(feature = "flag-add")] Self::Add(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "flag-set")] Self::Set(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "flag-remove")] Self::Remove(cmd) => cmd.execute(printer, config).await, } } diff --git a/src/email/envelope/flag/command/remove.rs b/src/email/envelope/flag/command/remove.rs index 4c0f1c1..4517fd5 100644 --- a/src/email/envelope/flag/command/remove.rs +++ b/src/email/envelope/flag/command/remove.rs @@ -8,10 +8,11 @@ use email::flag::remove::maildir::RemoveFlagsMaildir; use email::flag::remove::notmuch::RemoveFlagsNotmuch; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs}, folder::arg::name::FolderNameOptionalFlag, @@ -30,6 +31,7 @@ pub struct FlagRemoveCommand { #[command(flatten)] pub args: IdsAndFlagsArgs, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -45,6 +47,7 @@ impl FlagRemoveCommand { let (ids, flags) = into_tuple(&self.args.ids_and_flags); let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -55,11 +58,18 @@ impl FlagRemoveCommand { &account_config, remove_flags_kind, |builder| match remove_flags_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_remove_flags(|ctx| ctx.imap.as_ref().and_then(RemoveFlagsImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_remove_flags(|ctx| { ctx.maildir.as_ref().and_then(RemoveFlagsMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_remove_flags(|ctx| { ctx.maildir_for_sync @@ -67,11 +77,6 @@ impl FlagRemoveCommand { .and_then(RemoveFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_remove_flags(|ctx| ctx.imap.as_ref().and_then(RemoveFlagsImap::new)); - } _ => (), }, ) diff --git a/src/email/envelope/flag/command/set.rs b/src/email/envelope/flag/command/set.rs index 5326445..c55c01d 100644 --- a/src/email/envelope/flag/command/set.rs +++ b/src/email/envelope/flag/command/set.rs @@ -8,10 +8,11 @@ use email::flag::set::maildir::SetFlagsMaildir; use email::flag::set::notmuch::SetFlagsNotmuch; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs}, folder::arg::name::FolderNameOptionalFlag, @@ -30,6 +31,7 @@ pub struct FlagSetCommand { #[command(flatten)] pub args: IdsAndFlagsArgs, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -45,6 +47,7 @@ impl FlagSetCommand { let (ids, flags) = into_tuple(&self.args.ids_and_flags); let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -55,19 +58,21 @@ impl FlagSetCommand { &account_config, set_flags_kind, |builder| match set_flags_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder.set_set_flags(|ctx| ctx.imap.as_ref().and_then(SetFlagsImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder .set_set_flags(|ctx| ctx.maildir.as_ref().and_then(SetFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_set_flags(|ctx| { ctx.maildir_for_sync.as_ref().and_then(SetFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder.set_set_flags(|ctx| ctx.imap.as_ref().and_then(SetFlagsImap::new)); - } _ => (), }, ) diff --git a/src/email/envelope/flag/config.rs b/src/email/envelope/flag/config.rs index eb75af4..637e8b8 100644 --- a/src/email/envelope/flag/config.rs +++ b/src/email/envelope/flag/config.rs @@ -5,23 +5,30 @@ use crate::backend::BackendKind; #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FlagConfig { + #[cfg(feature = "flag-add")] pub add: Option, + #[cfg(feature = "flag-set")] pub set: Option, + #[cfg(feature = "flag-remove")] pub remove: Option, } impl FlagConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + #[allow(unused_mut)] let mut kinds = HashSet::default(); + #[cfg(feature = "flag-add")] if let Some(add) = &self.add { kinds.extend(add.get_used_backends()); } + #[cfg(feature = "flag-set")] if let Some(set) = &self.set { kinds.extend(set.get_used_backends()); } + #[cfg(feature = "flag-remove")] if let Some(remove) = &self.remove { kinds.extend(remove.get_used_backends()); } @@ -30,11 +37,13 @@ impl FlagConfig { } } +#[cfg(feature = "flag-add")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FlagAddConfig { pub backend: Option, } +#[cfg(feature = "flag-add")] impl FlagAddConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -47,11 +56,13 @@ impl FlagAddConfig { } } +#[cfg(feature = "flag-set")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FlagSetConfig { pub backend: Option, } +#[cfg(feature = "flag-set")] impl FlagSetConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -64,11 +75,13 @@ impl FlagSetConfig { } } +#[cfg(feature = "flag-remove")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FlagRemoveConfig { pub backend: Option, } +#[cfg(feature = "flag-remove")] impl FlagRemoveConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); diff --git a/src/email/envelope/mod.rs b/src/email/envelope/mod.rs index adde73b..de3df78 100644 --- a/src/email/envelope/mod.rs +++ b/src/email/envelope/mod.rs @@ -3,14 +3,19 @@ pub mod command; pub mod config; pub mod flag; +#[cfg(feature = "envelope-list")] use anyhow::Result; +#[cfg(feature = "envelope-list")] use email::account::config::AccountConfig; use serde::Serialize; +#[cfg(feature = "envelope-list")] use std::ops; +use crate::flag::Flags; +#[cfg(feature = "envelope-list")] use crate::{ cache::IdMapper, - flag::{Flag, Flags}, + flag::Flag, printer::{PrintTable, PrintTableOpts, WriteColor}, ui::{Cell, Row, Table}, }; @@ -30,6 +35,7 @@ pub struct Envelope { pub date: String, } +#[cfg(feature = "envelope-list")] impl Table for Envelope { fn head() -> Row { Row::new() @@ -75,10 +81,12 @@ impl Table for Envelope { } } +#[cfg(feature = "envelope-list")] /// Represents the list of envelopes. #[derive(Clone, Debug, Default, Serialize)] pub struct Envelopes(Vec); +#[cfg(feature = "envelope-list")] impl Envelopes { pub fn from_backend( config: &AccountConfig, @@ -105,6 +113,7 @@ impl Envelopes { } } +#[cfg(feature = "envelope-list")] impl ops::Deref for Envelopes { type Target = Vec; @@ -113,6 +122,7 @@ impl ops::Deref for Envelopes { } } +#[cfg(feature = "envelope-list")] impl PrintTable for Envelopes { fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> { writeln!(writer)?; diff --git a/src/email/message/attachment/command/download.rs b/src/email/message/attachment/command/download.rs index d9cab87..5ac8a21 100644 --- a/src/email/message/attachment/command/download.rs +++ b/src/email/message/attachment/command/download.rs @@ -1,17 +1,18 @@ use anyhow::{Context, Result}; use clap::Parser; #[cfg(feature = "imap")] -use email::message::{get::imap::GetMessagesImap, peek::imap::PeekMessagesImap}; +use email::message::get::imap::GetMessagesImap; #[cfg(feature = "maildir")] use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMessagesMaildir}; use log::info; use std::{fs, path::PathBuf}; use uuid::Uuid; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag, @@ -30,6 +31,7 @@ pub struct AttachmentDownloadCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -46,6 +48,7 @@ impl AttachmentDownloadCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -56,6 +59,12 @@ impl AttachmentDownloadCommand { &account_config, get_messages_kind, |builder| match get_messages_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_peek_messages(|ctx| { ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new) @@ -63,6 +72,7 @@ impl AttachmentDownloadCommand { builder .set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_peek_messages(|ctx| { ctx.maildir_for_sync @@ -73,13 +83,6 @@ impl AttachmentDownloadCommand { ctx.maildir_for_sync.as_ref().and_then(AddFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_peek_messages(|ctx| ctx.imap.as_ref().and_then(PeekMessagesImap::new)); - builder - .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); - } _ => (), }, ) diff --git a/src/email/message/attachment/command/mod.rs b/src/email/message/attachment/command/mod.rs index 5ae2c61..25c5c27 100644 --- a/src/email/message/attachment/command/mod.rs +++ b/src/email/message/attachment/command/mod.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "attachment-download")] pub mod download; use anyhow::Result; @@ -5,6 +6,7 @@ use clap::Subcommand; use crate::{config::TomlConfig, printer::Printer}; +#[cfg(feature = "attachment-download")] use self::download::AttachmentDownloadCommand; /// Manage attachments. @@ -14,13 +16,16 @@ use self::download::AttachmentDownloadCommand; /// body. #[derive(Debug, Subcommand)] pub enum AttachmentSubcommand { + #[cfg(feature = "attachment-download")] #[command(arg_required_else_help = true)] Download(AttachmentDownloadCommand), } impl AttachmentSubcommand { + #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { + #[cfg(feature = "attachment-download")] Self::Download(cmd) => cmd.execute(printer, config).await, } } diff --git a/src/email/message/command/copy.rs b/src/email/message/command/copy.rs index f77078b..e858068 100644 --- a/src/email/message/command/copy.rs +++ b/src/email/message/command/copy.rs @@ -6,10 +6,11 @@ use email::message::copy::imap::CopyMessagesImap; use email::message::copy::maildir::CopyMessagesMaildir; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::{SourceFolderNameOptionalFlag, TargetFolderNameArg}, @@ -28,6 +29,7 @@ pub struct MessageCopyCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -45,6 +47,7 @@ impl MessageCopyCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -55,11 +58,18 @@ impl MessageCopyCommand { &account_config, copy_messages_kind, |builder| match copy_messages_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_copy_messages(|ctx| ctx.imap.as_ref().and_then(CopyMessagesImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_copy_messages(|ctx| { ctx.maildir.as_ref().and_then(CopyMessagesMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_copy_messages(|ctx| { ctx.maildir_for_sync @@ -67,11 +77,6 @@ impl MessageCopyCommand { .and_then(CopyMessagesMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_copy_messages(|ctx| ctx.imap.as_ref().and_then(CopyMessagesImap::new)); - } _ => (), }, ) diff --git a/src/email/message/command/delete.rs b/src/email/message/command/delete.rs index 5bfbd95..4816a09 100644 --- a/src/email/message/command/delete.rs +++ b/src/email/message/command/delete.rs @@ -6,10 +6,11 @@ use email::{flag::add::imap::AddFlagsImap, message::move_::imap::MoveMessagesIma use email::{flag::add::maildir::AddFlagsMaildir, message::move_::maildir::MoveMessagesMaildir}; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag, @@ -30,6 +31,7 @@ pub struct MessageDeleteCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -46,6 +48,7 @@ impl MessageDeleteCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -56,6 +59,13 @@ impl MessageDeleteCommand { &account_config, delete_messages_kind, |builder| match delete_messages_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_move_messages(|ctx| ctx.imap.as_ref().and_then(MoveMessagesImap::new)); + builder.set_add_flags(|ctx| ctx.imap.as_ref().and_then(AddFlagsImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_move_messages(|ctx| { ctx.maildir.as_ref().and_then(MoveMessagesMaildir::new) @@ -63,6 +73,7 @@ impl MessageDeleteCommand { builder .set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_move_messages(|ctx| { ctx.maildir_for_sync @@ -73,12 +84,6 @@ impl MessageDeleteCommand { ctx.maildir_for_sync.as_ref().and_then(AddFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_move_messages(|ctx| ctx.imap.as_ref().and_then(MoveMessagesImap::new)); - builder.set_add_flags(|ctx| ctx.imap.as_ref().and_then(AddFlagsImap::new)); - } _ => (), }, ) diff --git a/src/email/message/command/forward.rs b/src/email/message/command/forward.rs index 276d645..19b75d2 100644 --- a/src/email/message/command/forward.rs +++ b/src/email/message/command/forward.rs @@ -1,19 +1,20 @@ use anyhow::{anyhow, Result}; use clap::Parser; #[cfg(feature = "imap")] -use email::message::add_raw::imap::AddRawMessageImap; +use email::message::add::imap::AddMessageImap; #[cfg(feature = "maildir")] -use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir; +use email::message::add_with_flags::maildir::AddMessageWithFlagsMaildir; #[cfg(feature = "sendmail")] -use email::message::send_raw::sendmail::SendRawMessageSendmail; +use email::message::send::sendmail::SendMessageSendmail; #[cfg(feature = "smtp")] -use email::message::send_raw::smtp::SendRawMessageSmtp; +use email::message::send::smtp::SendMessageSmtp; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdArg, folder::arg::name::FolderNameOptionalFlag, @@ -42,6 +43,7 @@ pub struct MessageForwardCommand { #[command(flatten)] pub body: MessageRawBodyArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -57,11 +59,12 @@ impl MessageForwardCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let add_message_kind = toml_account_config.add_raw_message_kind(); - let send_message_kind = toml_account_config.send_raw_message_kind(); + let add_message_kind = toml_account_config.add_message_kind(); + let send_message_kind = toml_account_config.send_message_kind(); let backend = Backend::new( &toml_account_config, @@ -69,24 +72,25 @@ impl MessageForwardCommand { add_message_kind.into_iter().chain(send_message_kind), |builder| { match add_message_kind { - Some(BackendKind::Maildir) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } #[cfg(feature = "imap")] Some(BackendKind::Imap) => { - builder.set_add_raw_message(|ctx| { - ctx.imap.as_ref().and_then(AddRawMessageImap::new) + builder + .set_add_message(|ctx| ctx.imap.as_ref().and_then(AddMessageImap::new)); + } + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) }); } _ => (), @@ -95,14 +99,14 @@ impl MessageForwardCommand { match send_message_kind { #[cfg(feature = "smtp")] Some(BackendKind::Smtp) => { - builder.set_send_raw_message(|ctx| { - ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new) + builder.set_send_message(|ctx| { + ctx.smtp.as_ref().and_then(SendMessageSmtp::new) }); } #[cfg(feature = "sendmail")] Some(BackendKind::Sendmail) => { - builder.set_send_raw_message(|ctx| { - ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new) + builder.set_send_message(|ctx| { + ctx.sendmail.as_ref().and_then(SendMessageSendmail::new) }); } _ => (), diff --git a/src/email/message/command/mailto.rs b/src/email/message/command/mailto.rs index a2b0470..55185d0 100644 --- a/src/email/message/command/mailto.rs +++ b/src/email/message/command/mailto.rs @@ -1,21 +1,22 @@ use anyhow::Result; use clap::Parser; #[cfg(feature = "imap")] -use email::message::add_raw::imap::AddRawMessageImap; +use email::message::add::imap::AddMessageImap; #[cfg(feature = "maildir")] -use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir; +use email::message::add_with_flags::maildir::AddMessageWithFlagsMaildir; #[cfg(feature = "sendmail")] -use email::message::send_raw::sendmail::SendRawMessageSendmail; +use email::message::send::sendmail::SendMessageSendmail; #[cfg(feature = "smtp")] -use email::message::send_raw::smtp::SendRawMessageSmtp; +use email::message::send::smtp::SendMessageSmtp; use log::{debug, info}; use mail_builder::MessageBuilder; use url::Url; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, printer::Printer, ui::editor, @@ -33,6 +34,7 @@ pub struct MessageMailtoCommand { #[arg()] pub url: Url, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -44,6 +46,7 @@ impl MessageMailtoCommand { pub fn new(url: &str) -> Result { Ok(Self { url: Url::parse(url)?, + #[cfg(feature = "sync")] cache: Default::default(), account: Default::default(), }) @@ -54,11 +57,12 @@ impl MessageMailtoCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let add_message_kind = toml_account_config.add_raw_message_kind(); - let send_message_kind = toml_account_config.send_raw_message_kind(); + let add_message_kind = toml_account_config.add_message_kind(); + let send_message_kind = toml_account_config.send_message_kind(); let backend = Backend::new( &toml_account_config, @@ -66,24 +70,25 @@ impl MessageMailtoCommand { add_message_kind.into_iter().chain(send_message_kind), |builder| { match add_message_kind { - Some(BackendKind::Maildir) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } #[cfg(feature = "imap")] Some(BackendKind::Imap) => { - builder.set_add_raw_message(|ctx| { - ctx.imap.as_ref().and_then(AddRawMessageImap::new) + builder + .set_add_message(|ctx| ctx.imap.as_ref().and_then(AddMessageImap::new)); + } + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) }); } _ => (), @@ -92,14 +97,14 @@ impl MessageMailtoCommand { match send_message_kind { #[cfg(feature = "smtp")] Some(BackendKind::Smtp) => { - builder.set_send_raw_message(|ctx| { - ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new) + builder.set_send_message(|ctx| { + ctx.smtp.as_ref().and_then(SendMessageSmtp::new) }); } #[cfg(feature = "sendmail")] Some(BackendKind::Sendmail) => { - builder.set_send_raw_message(|ctx| { - ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new) + builder.set_send_message(|ctx| { + ctx.sendmail.as_ref().and_then(SendMessageSendmail::new) }); } _ => (), diff --git a/src/email/message/command/mod.rs b/src/email/message/command/mod.rs index 9036b46..fc87d0f 100644 --- a/src/email/message/command/mod.rs +++ b/src/email/message/command/mod.rs @@ -1,12 +1,22 @@ +#[cfg(feature = "message-copy")] pub mod copy; +#[cfg(feature = "message-delete")] pub mod delete; +#[cfg(feature = "message-forward")] pub mod forward; +#[cfg(feature = "message-mailto")] pub mod mailto; +#[cfg(feature = "message-move")] pub mod move_; +#[cfg(feature = "message-read")] pub mod read; +#[cfg(feature = "message-reply")] pub mod reply; +#[cfg(feature = "message-save")] pub mod save; +#[cfg(feature = "message-send")] pub mod send; +#[cfg(feature = "message-write")] pub mod write; use anyhow::Result; @@ -14,12 +24,26 @@ use clap::Subcommand; use crate::{config::TomlConfig, printer::Printer}; -use self::{ - copy::MessageCopyCommand, delete::MessageDeleteCommand, forward::MessageForwardCommand, - mailto::MessageMailtoCommand, move_::MessageMoveCommand, read::MessageReadCommand, - reply::MessageReplyCommand, save::MessageSaveCommand, send::MessageSendCommand, - write::MessageWriteCommand, -}; +#[cfg(feature = "message-copy")] +use self::copy::MessageCopyCommand; +#[cfg(feature = "message-delete")] +use self::delete::MessageDeleteCommand; +#[cfg(feature = "message-forward")] +use self::forward::MessageForwardCommand; +#[cfg(feature = "message-mailto")] +use self::mailto::MessageMailtoCommand; +#[cfg(feature = "message-move")] +use self::move_::MessageMoveCommand; +#[cfg(feature = "message-read")] +use self::read::MessageReadCommand; +#[cfg(feature = "message-reply")] +use self::reply::MessageReplyCommand; +#[cfg(feature = "message-save")] +use self::save::MessageSaveCommand; +#[cfg(feature = "message-send")] +use self::send::MessageSendCommand; +#[cfg(feature = "message-write")] +use self::write::MessageWriteCommand; /// Manage messages. /// @@ -29,52 +53,73 @@ use self::{ /// subcommand allows you to manage them. #[derive(Debug, Subcommand)] pub enum MessageSubcommand { + #[cfg(feature = "message-read")] #[command(arg_required_else_help = true)] Read(MessageReadCommand), + #[cfg(feature = "message-write")] #[command(aliases = ["add", "create", "new", "compose"])] Write(MessageWriteCommand), + #[cfg(feature = "message-reply")] #[command()] Reply(MessageReplyCommand), + #[cfg(feature = "message-forward")] #[command(aliases = ["fwd", "fd"])] Forward(MessageForwardCommand), + #[cfg(feature = "message-mailto")] #[command()] Mailto(MessageMailtoCommand), + #[cfg(feature = "message-save")] #[command(arg_required_else_help = true)] Save(MessageSaveCommand), + #[cfg(feature = "message-send")] #[command(arg_required_else_help = true)] Send(MessageSendCommand), + #[cfg(feature = "message-copy")] #[command(arg_required_else_help = true)] #[command(aliases = ["cpy", "cp"])] Copy(MessageCopyCommand), + #[cfg(feature = "message-move")] #[command(arg_required_else_help = true)] #[command(alias = "mv")] Move(MessageMoveCommand), + #[cfg(feature = "message-delete")] #[command(arg_required_else_help = true)] #[command(aliases = ["remove", "rm"])] Delete(MessageDeleteCommand), } impl MessageSubcommand { + #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { + #[cfg(feature = "message-read")] Self::Read(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-write")] Self::Write(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-reply")] Self::Reply(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-forward")] Self::Forward(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-mailto")] Self::Mailto(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-save")] Self::Save(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-send")] Self::Send(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-copy")] Self::Copy(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-move")] Self::Move(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "message-delete")] Self::Delete(cmd) => cmd.execute(printer, config).await, } } diff --git a/src/email/message/command/move_.rs b/src/email/message/command/move_.rs index 9995e46..67f574d 100644 --- a/src/email/message/command/move_.rs +++ b/src/email/message/command/move_.rs @@ -6,10 +6,11 @@ use email::message::move_::imap::MoveMessagesImap; use email::message::move_::maildir::MoveMessagesMaildir; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::{SourceFolderNameOptionalFlag, TargetFolderNameArg}, @@ -28,6 +29,7 @@ pub struct MessageMoveCommand { #[command(flatten)] pub envelopes: EnvelopeIdsArgs, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -45,6 +47,7 @@ impl MessageMoveCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -55,11 +58,18 @@ impl MessageMoveCommand { &account_config, move_messages_kind, |builder| match move_messages_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_move_messages(|ctx| ctx.imap.as_ref().and_then(MoveMessagesImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_move_messages(|ctx| { ctx.maildir.as_ref().and_then(MoveMessagesMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_move_messages(|ctx| { ctx.maildir_for_sync @@ -67,11 +77,6 @@ impl MessageMoveCommand { .and_then(MoveMessagesMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_move_messages(|ctx| ctx.imap.as_ref().and_then(MoveMessagesImap::new)); - } _ => (), }, ) diff --git a/src/email/message/command/read.rs b/src/email/message/command/read.rs index 60e71c1..e17936d 100644 --- a/src/email/message/command/read.rs +++ b/src/email/message/command/read.rs @@ -7,10 +7,11 @@ use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMes use log::info; use mml::message::FilterParts; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, folder::arg::name::FolderNameOptionalFlag, @@ -74,6 +75,7 @@ pub struct MessageReadCommand { #[arg(conflicts_with = "no_headers")] pub headers: Vec, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -90,6 +92,7 @@ impl MessageReadCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -100,6 +103,14 @@ impl MessageReadCommand { &account_config, get_messages_kind, |builder| match get_messages_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_peek_messages(|ctx| ctx.imap.as_ref().and_then(PeekMessagesImap::new)); + builder + .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_peek_messages(|ctx| { ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new) @@ -107,6 +118,7 @@ impl MessageReadCommand { builder .set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_peek_messages(|ctx| { ctx.maildir_for_sync @@ -117,13 +129,6 @@ impl MessageReadCommand { ctx.maildir_for_sync.as_ref().and_then(AddFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_peek_messages(|ctx| ctx.imap.as_ref().and_then(PeekMessagesImap::new)); - builder - .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); - } _ => (), }, ) diff --git a/src/email/message/command/reply.rs b/src/email/message/command/reply.rs index db14c2c..8dc56ea 100644 --- a/src/email/message/command/reply.rs +++ b/src/email/message/command/reply.rs @@ -2,19 +2,20 @@ use anyhow::{anyhow, Result}; use clap::Parser; use email::flag::Flag; #[cfg(feature = "imap")] -use email::message::add_raw::imap::AddRawMessageImap; +use email::message::add::imap::AddMessageImap; #[cfg(feature = "maildir")] -use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir; +use email::message::add_with_flags::maildir::AddMessageWithFlagsMaildir; #[cfg(feature = "sendmail")] -use email::message::send_raw::sendmail::SendRawMessageSendmail; +use email::message::send::sendmail::SendMessageSendmail; #[cfg(feature = "smtp")] -use email::message::send_raw::smtp::SendRawMessageSmtp; +use email::message::send::smtp::SendMessageSmtp; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdArg, folder::arg::name::FolderNameOptionalFlag, @@ -46,6 +47,7 @@ pub struct MessageReplyCommand { #[command(flatten)] pub body: MessageRawBodyArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -60,11 +62,12 @@ impl MessageReplyCommand { let folder = &self.folder.name; let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let add_message_kind = toml_account_config.add_raw_message_kind(); - let send_message_kind = toml_account_config.send_raw_message_kind(); + let add_message_kind = toml_account_config.add_message_kind(); + let send_message_kind = toml_account_config.send_message_kind(); let backend = Backend::new( &toml_account_config, @@ -72,24 +75,25 @@ impl MessageReplyCommand { add_message_kind.into_iter().chain(send_message_kind), |builder| { match add_message_kind { - Some(BackendKind::Maildir) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } #[cfg(feature = "imap")] Some(BackendKind::Imap) => { - builder.set_add_raw_message(|ctx| { - ctx.imap.as_ref().and_then(AddRawMessageImap::new) + builder + .set_add_message(|ctx| ctx.imap.as_ref().and_then(AddMessageImap::new)); + } + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) }); } _ => (), @@ -98,14 +102,14 @@ impl MessageReplyCommand { match send_message_kind { #[cfg(feature = "smtp")] Some(BackendKind::Smtp) => { - builder.set_send_raw_message(|ctx| { - ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new) + builder.set_send_message(|ctx| { + ctx.smtp.as_ref().and_then(SendMessageSmtp::new) }); } #[cfg(feature = "sendmail")] Some(BackendKind::Sendmail) => { - builder.set_send_raw_message(|ctx| { - ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new) + builder.set_send_message(|ctx| { + ctx.sendmail.as_ref().and_then(SendMessageSendmail::new) }); } _ => (), @@ -128,7 +132,7 @@ impl MessageReplyCommand { .await?; editor::edit_tpl_with_editor(&account_config, printer, &backend, tpl).await?; - // TODO: let backend.send_reply_raw_message adding the flag + // TODO: let backend.send_reply_message adding the flag backend.add_flag(&folder, &[id], Flag::Answered).await } } diff --git a/src/email/message/command/save.rs b/src/email/message/command/save.rs index cf2ec59..1eb4ae4 100644 --- a/src/email/message/command/save.rs +++ b/src/email/message/command/save.rs @@ -1,16 +1,17 @@ use anyhow::Result; use clap::Parser; #[cfg(feature = "imap")] -use email::message::add_raw::imap::AddRawMessageImap; +use email::message::add::imap::AddMessageImap; #[cfg(feature = "maildir")] -use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir; +use email::message::add_with_flags::maildir::AddMessageWithFlagsMaildir; use log::info; use std::io::{self, BufRead, IsTerminal}; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, folder::arg::name::FolderNameOptionalFlag, message::arg::MessageRawArg, @@ -28,6 +29,7 @@ pub struct MessageSaveCommand { #[command(flatten)] pub message: MessageRawArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -43,34 +45,35 @@ impl MessageSaveCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let add_message_kind = toml_account_config.add_raw_message_kind(); + let add_message_kind = toml_account_config.add_message_kind(); let backend = Backend::new( &toml_account_config, &account_config, add_message_kind, |builder| match add_message_kind { - Some(BackendKind::Maildir) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } #[cfg(feature = "imap")] Some(BackendKind::Imap) => { - builder.set_add_raw_message(|ctx| { - ctx.imap.as_ref().and_then(AddRawMessageImap::new) + builder.set_add_message(|ctx| ctx.imap.as_ref().and_then(AddMessageImap::new)); + } + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) }); } _ => (), @@ -91,7 +94,7 @@ impl MessageSaveCommand { .join("\r\n") }; - backend.add_raw_message(folder, msg.as_bytes()).await?; + backend.add_message(folder, msg.as_bytes()).await?; printer.print(format!("Message successfully saved to {folder}!")) } diff --git a/src/email/message/command/send.rs b/src/email/message/command/send.rs index ad1fded..4e6c729 100644 --- a/src/email/message/command/send.rs +++ b/src/email/message/command/send.rs @@ -1,16 +1,17 @@ use anyhow::Result; use clap::Parser; #[cfg(feature = "sendmail")] -use email::message::send_raw::sendmail::SendRawMessageSendmail; +use email::message::send::sendmail::SendMessageSendmail; #[cfg(feature = "smtp")] -use email::message::send_raw::smtp::SendRawMessageSmtp; +use email::message::send::smtp::SendMessageSmtp; use log::info; use std::io::{self, BufRead, IsTerminal}; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, message::arg::MessageRawArg, printer::Printer, @@ -25,6 +26,7 @@ pub struct MessageSendCommand { #[command(flatten)] pub message: MessageRawArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -38,10 +40,11 @@ impl MessageSendCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let send_message_kind = toml_account_config.send_raw_message_kind(); + let send_message_kind = toml_account_config.send_message_kind(); let backend = Backend::new( &toml_account_config, @@ -51,14 +54,14 @@ impl MessageSendCommand { match send_message_kind { #[cfg(feature = "smtp")] Some(BackendKind::Smtp) => { - builder.set_send_raw_message(|ctx| { - ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new) + builder.set_send_message(|ctx| { + ctx.smtp.as_ref().and_then(SendMessageSmtp::new) }); } #[cfg(feature = "sendmail")] Some(BackendKind::Sendmail) => { - builder.set_send_raw_message(|ctx| { - ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new) + builder.set_send_message(|ctx| { + ctx.sendmail.as_ref().and_then(SendMessageSendmail::new) }); } _ => (), @@ -78,7 +81,7 @@ impl MessageSendCommand { .join("\r\n") }; - backend.send_raw_message(msg.as_bytes()).await?; + backend.send_message(msg.as_bytes()).await?; printer.print("Message successfully sent!") } diff --git a/src/email/message/command/write.rs b/src/email/message/command/write.rs index ce326cc..18bccda 100644 --- a/src/email/message/command/write.rs +++ b/src/email/message/command/write.rs @@ -1,20 +1,21 @@ use anyhow::Result; use clap::Parser; #[cfg(feature = "imap")] -use email::message::add_raw::imap::AddRawMessageImap; +use email::message::add::imap::AddMessageImap; #[cfg(feature = "maildir")] -use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir; +use email::message::add_with_flags::maildir::AddMessageWithFlagsMaildir; #[cfg(feature = "sendmail")] -use email::message::send_raw::sendmail::SendRawMessageSendmail; +use email::message::send::sendmail::SendMessageSendmail; #[cfg(feature = "smtp")] -use email::message::send_raw::smtp::SendRawMessageSmtp; +use email::message::send::smtp::SendMessageSmtp; use email::message::Message; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs}, printer::Printer, @@ -35,6 +36,7 @@ pub struct MessageWriteCommand { #[command(flatten)] pub body: MessageRawBodyArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -48,11 +50,12 @@ impl MessageWriteCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let add_message_kind = toml_account_config.add_raw_message_kind(); - let send_message_kind = toml_account_config.send_raw_message_kind(); + let add_message_kind = toml_account_config.add_message_kind(); + let send_message_kind = toml_account_config.send_message_kind(); let backend = Backend::new( &toml_account_config, @@ -60,24 +63,25 @@ impl MessageWriteCommand { add_message_kind.into_iter().chain(send_message_kind), |builder| { match add_message_kind { - Some(BackendKind::Maildir) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } #[cfg(feature = "imap")] Some(BackendKind::Imap) => { - builder.set_add_raw_message(|ctx| { - ctx.imap.as_ref().and_then(AddRawMessageImap::new) + builder + .set_add_message(|ctx| ctx.imap.as_ref().and_then(AddMessageImap::new)); + } + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) }); } _ => (), @@ -86,14 +90,14 @@ impl MessageWriteCommand { match send_message_kind { #[cfg(feature = "smtp")] Some(BackendKind::Smtp) => { - builder.set_send_raw_message(|ctx| { - ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new) + builder.set_send_message(|ctx| { + ctx.smtp.as_ref().and_then(SendMessageSmtp::new) }); } #[cfg(feature = "sendmail")] Some(BackendKind::Sendmail) => { - builder.set_send_raw_message(|ctx| { - ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new) + builder.set_send_message(|ctx| { + ctx.sendmail.as_ref().and_then(SendMessageSendmail::new) }); } _ => (), diff --git a/src/email/message/config.rs b/src/email/message/config.rs index 4d95ef4..a150e3a 100644 --- a/src/email/message/config.rs +++ b/src/email/message/config.rs @@ -5,39 +5,52 @@ use crate::backend::BackendKind; #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageConfig { + #[cfg(any(feature = "message-add", feature = "message-write"))] pub write: Option, + #[cfg(any(feature = "message-send", feature = "template-send"))] pub send: Option, + #[cfg(feature = "message-peek")] pub peek: Option, + #[cfg(any(feature = "message-get", feature = "message-read"))] pub read: Option, + #[cfg(feature = "message-copy")] pub copy: Option, + #[cfg(feature = "message-move")] #[serde(rename = "move")] pub move_: Option, } impl MessageConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + #[allow(unused_mut)] let mut kinds = HashSet::default(); + #[cfg(any(feature = "message-add", feature = "message-write"))] if let Some(add) = &self.write { kinds.extend(add.get_used_backends()); } + #[cfg(any(feature = "message-send", feature = "template-send"))] if let Some(send) = &self.send { kinds.extend(send.get_used_backends()); } + #[cfg(feature = "message-peek")] if let Some(peek) = &self.peek { kinds.extend(peek.get_used_backends()); } + #[cfg(any(feature = "message-get", feature = "message-read"))] if let Some(get) = &self.read { kinds.extend(get.get_used_backends()); } + #[cfg(feature = "message-copy")] if let Some(copy) = &self.copy { kinds.extend(copy.get_used_backends()); } + #[cfg(feature = "message-move")] if let Some(move_) = &self.move_ { kinds.extend(move_.get_used_backends()); } @@ -46,14 +59,16 @@ impl MessageConfig { } } +#[cfg(any(feature = "message-add", feature = "message-write"))] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageAddConfig { pub backend: Option, #[serde(flatten)] - pub remote: email::message::add_raw::config::MessageWriteConfig, + pub remote: email::message::add::config::MessageWriteConfig, } +#[cfg(any(feature = "message-add", feature = "message-write"))] impl MessageAddConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -66,14 +81,16 @@ impl MessageAddConfig { } } +#[cfg(any(feature = "message-send", feature = "template-send"))] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageSendConfig { pub backend: Option, #[serde(flatten)] - pub remote: email::message::send_raw::config::MessageSendConfig, + pub remote: email::message::send::config::MessageSendConfig, } +#[cfg(any(feature = "message-send", feature = "template-send"))] impl MessageSendConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -86,11 +103,13 @@ impl MessageSendConfig { } } +#[cfg(feature = "message-peek")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessagePeekConfig { pub backend: Option, } +#[cfg(feature = "message-peek")] impl MessagePeekConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -103,6 +122,7 @@ impl MessagePeekConfig { } } +#[cfg(any(feature = "message-get", feature = "message-read"))] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageGetConfig { pub backend: Option, @@ -111,6 +131,7 @@ pub struct MessageGetConfig { pub remote: email::message::get::config::MessageReadConfig, } +#[cfg(any(feature = "message-get", feature = "message-read"))] impl MessageGetConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -123,11 +144,13 @@ impl MessageGetConfig { } } +#[cfg(feature = "message-copy")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageCopyConfig { pub backend: Option, } +#[cfg(feature = "message-copy")] impl MessageCopyConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -140,11 +163,13 @@ impl MessageCopyConfig { } } +#[cfg(feature = "message-move")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct MessageMoveConfig { pub backend: Option, } +#[cfg(feature = "message-move")] impl MessageMoveConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); diff --git a/src/email/message/template/command/forward.rs b/src/email/message/template/command/forward.rs index d035d56..379f40e 100644 --- a/src/email/message/template/command/forward.rs +++ b/src/email/message/template/command/forward.rs @@ -1,15 +1,16 @@ use anyhow::{anyhow, Result}; use clap::Parser; #[cfg(feature = "imap")] -use email::message::{get::imap::GetMessagesImap, peek::imap::PeekMessagesImap}; +use email::message::get::imap::GetMessagesImap; #[cfg(feature = "maildir")] use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMessagesMaildir}; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdArg, folder::arg::name::FolderNameOptionalFlag, @@ -36,6 +37,7 @@ pub struct TemplateForwardCommand { #[command(flatten)] pub body: MessageRawBodyArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -51,6 +53,7 @@ impl TemplateForwardCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -61,6 +64,12 @@ impl TemplateForwardCommand { &account_config, get_messages_kind, |builder| match get_messages_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_peek_messages(|ctx| { ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new) @@ -68,6 +77,7 @@ impl TemplateForwardCommand { builder .set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_peek_messages(|ctx| { ctx.maildir_for_sync @@ -78,13 +88,6 @@ impl TemplateForwardCommand { ctx.maildir_for_sync.as_ref().and_then(AddFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_peek_messages(|ctx| ctx.imap.as_ref().and_then(PeekMessagesImap::new)); - builder - .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); - } _ => (), }, ) diff --git a/src/email/message/template/command/mod.rs b/src/email/message/template/command/mod.rs index fa4bab7..c1631b2 100644 --- a/src/email/message/template/command/mod.rs +++ b/src/email/message/template/command/mod.rs @@ -1,7 +1,12 @@ +#[cfg(feature = "template-forward")] pub mod forward; +#[cfg(feature = "template-reply")] pub mod reply; +#[cfg(feature = "template-save")] pub mod save; +#[cfg(feature = "template-send")] pub mod send; +#[cfg(feature = "template-write")] pub mod write; use anyhow::Result; @@ -9,10 +14,16 @@ use clap::Subcommand; use crate::{config::TomlConfig, printer::Printer}; -use self::{ - forward::TemplateForwardCommand, reply::TemplateReplyCommand, save::TemplateSaveCommand, - send::TemplateSendCommand, write::TemplateWriteCommand, -}; +#[cfg(feature = "template-forward")] +use self::forward::TemplateForwardCommand; +#[cfg(feature = "template-reply")] +use self::reply::TemplateReplyCommand; +#[cfg(feature = "template-save")] +use self::save::TemplateSaveCommand; +#[cfg(feature = "template-send")] +use self::send::TemplateSendCommand; +#[cfg(feature = "template-write")] +use self::write::TemplateWriteCommand; /// Manage templates. /// @@ -25,30 +36,41 @@ use self::{ /// . #[derive(Debug, Subcommand)] pub enum TemplateSubcommand { + #[cfg(feature = "template-write")] #[command(aliases = ["add", "create", "new", "compose"])] Write(TemplateWriteCommand), + #[cfg(feature = "template-reply")] #[command(arg_required_else_help = true)] Reply(TemplateReplyCommand), + #[cfg(feature = "template-forward")] #[command(arg_required_else_help = true)] #[command(alias = "fwd")] Forward(TemplateForwardCommand), + #[cfg(feature = "template-save")] #[command()] Save(TemplateSaveCommand), + #[cfg(feature = "template-send")] #[command()] Send(TemplateSendCommand), } impl TemplateSubcommand { + #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { + #[cfg(feature = "template-write")] Self::Write(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "template-reply")] Self::Reply(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "template-forward")] Self::Forward(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "template-save")] Self::Save(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "template-send")] Self::Send(cmd) => cmd.execute(printer, config).await, } } diff --git a/src/email/message/template/command/reply.rs b/src/email/message/template/command/reply.rs index 57342db..928c6b5 100644 --- a/src/email/message/template/command/reply.rs +++ b/src/email/message/template/command/reply.rs @@ -1,15 +1,16 @@ use anyhow::{anyhow, Result}; use clap::Parser; #[cfg(feature = "imap")] -use email::message::{get::imap::GetMessagesImap, peek::imap::PeekMessagesImap}; +use email::message::get::imap::GetMessagesImap; #[cfg(feature = "maildir")] use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMessagesMaildir}; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, envelope::arg::ids::EnvelopeIdArg, folder::arg::name::FolderNameOptionalFlag, @@ -40,6 +41,7 @@ pub struct TemplateReplyCommand { #[command(flatten)] pub body: MessageRawBodyArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -56,6 +58,7 @@ impl TemplateReplyCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -66,6 +69,12 @@ impl TemplateReplyCommand { &account_config, get_messages_kind, |builder| match get_messages_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_peek_messages(|ctx| { ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new) @@ -73,6 +82,7 @@ impl TemplateReplyCommand { builder .set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_peek_messages(|ctx| { ctx.maildir_for_sync @@ -83,13 +93,6 @@ impl TemplateReplyCommand { ctx.maildir_for_sync.as_ref().and_then(AddFlagsMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_peek_messages(|ctx| ctx.imap.as_ref().and_then(PeekMessagesImap::new)); - builder - .set_get_messages(|ctx| ctx.imap.as_ref().and_then(GetMessagesImap::new)); - } _ => (), }, ) diff --git a/src/email/message/template/command/save.rs b/src/email/message/template/command/save.rs index f972478..93120f6 100644 --- a/src/email/message/template/command/save.rs +++ b/src/email/message/template/command/save.rs @@ -1,17 +1,18 @@ use anyhow::Result; use clap::Parser; #[cfg(feature = "imap")] -use email::message::add_raw::imap::AddRawMessageImap; +use email::message::add::imap::AddMessageImap; #[cfg(feature = "maildir")] -use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir; +use email::message::add_with_flags::maildir::AddMessageWithFlagsMaildir; use log::info; use mml::MmlCompilerBuilder; use std::io::{self, BufRead, IsTerminal}; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, email::template::arg::TemplateRawArg, folder::arg::name::FolderNameOptionalFlag, @@ -32,6 +33,7 @@ pub struct TemplateSaveCommand { #[command(flatten)] pub template: TemplateRawArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -47,34 +49,35 @@ impl TemplateSaveCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let add_message_kind = toml_account_config.add_raw_message_kind(); + let add_message_kind = toml_account_config.add_message_kind(); let backend = Backend::new( &toml_account_config, &account_config, add_message_kind, |builder| match add_message_kind { - Some(BackendKind::Maildir) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } - Some(BackendKind::MaildirForSync) => { - builder.set_add_raw_message_with_flags(|ctx| { - ctx.maildir_for_sync - .as_ref() - .and_then(AddRawMessageWithFlagsMaildir::new) - }); - } #[cfg(feature = "imap")] Some(BackendKind::Imap) => { - builder.set_add_raw_message(|ctx| { - ctx.imap.as_ref().and_then(AddRawMessageImap::new) + builder.set_add_message(|ctx| ctx.imap.as_ref().and_then(AddMessageImap::new)); + } + #[cfg(feature = "maildir")] + Some(BackendKind::Maildir) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) + }); + } + #[cfg(feature = "sync")] + Some(BackendKind::MaildirForSync) => { + builder.set_add_message_with_flags(|ctx| { + ctx.maildir_for_sync + .as_ref() + .and_then(AddMessageWithFlagsMaildir::new) }); } _ => (), @@ -102,7 +105,8 @@ impl TemplateSaveCommand { compiler.set_some_pgp(account_config.pgp.clone()); let msg = compiler.build(tpl.as_str())?.compile().await?.into_vec()?; - backend.add_raw_message(folder, &msg).await?; + + backend.add_message(folder, &msg).await?; printer.print(format!("Template successfully saved to {folder}!")) } diff --git a/src/email/message/template/command/send.rs b/src/email/message/template/command/send.rs index f565ce1..77281a7 100644 --- a/src/email/message/template/command/send.rs +++ b/src/email/message/template/command/send.rs @@ -1,17 +1,18 @@ use anyhow::Result; use clap::Parser; #[cfg(feature = "sendmail")] -use email::message::send_raw::sendmail::SendRawMessageSendmail; +use email::message::send::sendmail::SendMessageSendmail; #[cfg(feature = "smtp")] -use email::message::send_raw::smtp::SendRawMessageSmtp; +use email::message::send::smtp::SendMessageSmtp; use log::info; use mml::MmlCompilerBuilder; use std::io::{self, BufRead, IsTerminal}; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, config::TomlConfig, email::template::arg::TemplateRawArg, printer::Printer, @@ -28,6 +29,7 @@ pub struct TemplateSendCommand { #[command(flatten)] pub template: TemplateRawArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -41,10 +43,11 @@ impl TemplateSendCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; - let send_message_kind = toml_account_config.send_raw_message_kind(); + let send_message_kind = toml_account_config.send_message_kind(); let backend = Backend::new( &toml_account_config, @@ -54,14 +57,14 @@ impl TemplateSendCommand { match send_message_kind { #[cfg(feature = "smtp")] Some(BackendKind::Smtp) => { - builder.set_send_raw_message(|ctx| { - ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new) + builder.set_send_message(|ctx| { + ctx.smtp.as_ref().and_then(SendMessageSmtp::new) }); } #[cfg(feature = "sendmail")] Some(BackendKind::Sendmail) => { - builder.set_send_raw_message(|ctx| { - ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new) + builder.set_send_message(|ctx| { + ctx.sendmail.as_ref().and_then(SendMessageSendmail::new) }); } _ => (), @@ -89,8 +92,8 @@ impl TemplateSendCommand { let msg = compiler.build(tpl.as_str())?.compile().await?.into_vec()?; - backend.send_raw_message(&msg).await?; + backend.send_message(&msg).await?; - printer.print("Template successfully sent!") + printer.print("Message successfully sent!") } } diff --git a/src/email/message/template/command/write.rs b/src/email/message/template/command/write.rs index 7034555..733a3ea 100644 --- a/src/email/message/template/command/write.rs +++ b/src/email/message/template/command/write.rs @@ -3,8 +3,10 @@ use clap::Parser; use email::message::Message; use log::info; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ - account::arg::name::AccountNameFlag, cache::arg::disable::CacheDisableFlag, config::TomlConfig, + account::arg::name::AccountNameFlag, config::TomlConfig, email::template::arg::body::TemplateRawBodyArg, message::arg::header::HeaderRawArgs, printer::Printer, }; @@ -21,6 +23,7 @@ pub struct TemplateWriteCommand { #[command(flatten)] pub body: TemplateRawBodyArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -34,6 +37,7 @@ impl TemplateWriteCommand { let (_, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; diff --git a/src/folder/command/create.rs b/src/folder/command/create.rs index 7125154..c59aa4f 100644 --- a/src/folder/command/create.rs +++ b/src/folder/command/create.rs @@ -6,13 +6,13 @@ use email::folder::add::imap::AddFolderImap; use email::folder::add::maildir::AddFolderMaildir; use log::info; +#[cfg(any(feature = "imap", feature = "maildir", feature = "sync"))] +use crate::backend::BackendKind; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ - account::arg::name::AccountNameFlag, - backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, - config::TomlConfig, - folder::arg::name::FolderNameArg, - printer::Printer, + account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, + folder::arg::name::FolderNameArg, printer::Printer, }; /// Create a new folder. @@ -20,10 +20,11 @@ use crate::{ /// This command allows you to create a new folder using the given /// name. #[derive(Debug, Parser)] -pub struct FolderCreateCommand { +pub struct AddFolderCommand { #[command(flatten)] pub folder: FolderNameArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -31,13 +32,14 @@ pub struct FolderCreateCommand { pub account: AccountNameFlag, } -impl FolderCreateCommand { +impl AddFolderCommand { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { info!("executing create folder command"); let folder = &self.folder.name; let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -48,10 +50,16 @@ impl FolderCreateCommand { &account_config, add_folder_kind, |builder| match add_folder_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder.set_add_folder(|ctx| ctx.imap.as_ref().and_then(AddFolderImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder .set_add_folder(|ctx| ctx.maildir.as_ref().and_then(AddFolderMaildir::new)); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_add_folder(|ctx| { ctx.maildir_for_sync @@ -59,10 +67,6 @@ impl FolderCreateCommand { .and_then(AddFolderMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder.set_add_folder(|ctx| ctx.imap.as_ref().and_then(AddFolderImap::new)); - } _ => (), }, ) diff --git a/src/folder/command/delete.rs b/src/folder/command/delete.rs index 8ce3881..3b99167 100644 --- a/src/folder/command/delete.rs +++ b/src/folder/command/delete.rs @@ -8,13 +8,13 @@ use email::folder::delete::maildir::DeleteFolderMaildir; use log::info; use std::process; +#[cfg(any(feature = "imap", feature = "maildir", feature = "sync"))] +use crate::backend::BackendKind; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ - account::arg::name::AccountNameFlag, - backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, - config::TomlConfig, - folder::arg::name::FolderNameArg, - printer::Printer, + account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, + folder::arg::name::FolderNameArg, printer::Printer, }; /// Delete a folder. @@ -26,6 +26,7 @@ pub struct FolderDeleteCommand { #[command(flatten)] pub folder: FolderNameArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -51,6 +52,7 @@ impl FolderDeleteCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -61,11 +63,18 @@ impl FolderDeleteCommand { &account_config, delete_folder_kind, |builder| match delete_folder_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_delete_folder(|ctx| ctx.imap.as_ref().and_then(DeleteFolderImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_delete_folder(|ctx| { ctx.maildir.as_ref().and_then(DeleteFolderMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_delete_folder(|ctx| { ctx.maildir_for_sync @@ -73,11 +82,6 @@ impl FolderDeleteCommand { .and_then(DeleteFolderMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_delete_folder(|ctx| ctx.imap.as_ref().and_then(DeleteFolderImap::new)); - } _ => (), }, ) diff --git a/src/folder/command/expunge.rs b/src/folder/command/expunge.rs index 5ad20a9..b2dc5ec 100644 --- a/src/folder/command/expunge.rs +++ b/src/folder/command/expunge.rs @@ -6,13 +6,13 @@ use email::folder::expunge::imap::ExpungeFolderImap; use email::folder::expunge::maildir::ExpungeFolderMaildir; use log::info; +#[cfg(any(feature = "imap", feature = "maildir", feature = "sync"))] +use crate::backend::BackendKind; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ - account::arg::name::AccountNameFlag, - backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, - config::TomlConfig, - folder::arg::name::FolderNameArg, - printer::Printer, + account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, + folder::arg::name::FolderNameArg, printer::Printer, }; /// Expunge a folder. @@ -25,6 +25,7 @@ pub struct FolderExpungeCommand { #[command(flatten)] pub folder: FolderNameArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -39,6 +40,7 @@ impl FolderExpungeCommand { let folder = &self.folder.name; let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -49,11 +51,19 @@ impl FolderExpungeCommand { &account_config, expunge_folder_kind, |builder| match expunge_folder_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder.set_expunge_folder(|ctx| { + ctx.imap.as_ref().and_then(ExpungeFolderImap::new) + }); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_expunge_folder(|ctx| { ctx.maildir.as_ref().and_then(ExpungeFolderMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_expunge_folder(|ctx| { ctx.maildir_for_sync @@ -61,12 +71,6 @@ impl FolderExpungeCommand { .and_then(ExpungeFolderMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder.set_expunge_folder(|ctx| { - ctx.imap.as_ref().and_then(ExpungeFolderImap::new) - }); - } _ => (), }, ) diff --git a/src/folder/command/list.rs b/src/folder/command/list.rs index f14e2d0..c9ef665 100644 --- a/src/folder/command/list.rs +++ b/src/folder/command/list.rs @@ -6,10 +6,13 @@ use email::folder::list::imap::ListFoldersImap; use email::folder::list::maildir::ListFoldersMaildir; use log::info; +#[cfg(any(feature = "imap", feature = "maildir", feature = "sync"))] +use crate::backend::BackendKind; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ account::arg::name::AccountNameFlag, - backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, + backend::Backend, config::TomlConfig, folder::Folders, printer::{PrintTableOpts, Printer}, @@ -24,6 +27,7 @@ pub struct FolderListCommand { #[command(flatten)] pub table: TableMaxWidthFlag, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -37,6 +41,7 @@ impl FolderListCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -47,11 +52,18 @@ impl FolderListCommand { &account_config, list_folders_kind, |builder| match list_folders_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_list_folders(|ctx| ctx.imap.as_ref().and_then(ListFoldersImap::new)); + } + #[cfg(feature = "maildir")] Some(BackendKind::Maildir) => { builder.set_list_folders(|ctx| { ctx.maildir.as_ref().and_then(ListFoldersMaildir::new) }); } + #[cfg(feature = "sync")] Some(BackendKind::MaildirForSync) => { builder.set_list_folders(|ctx| { ctx.maildir_for_sync @@ -59,11 +71,6 @@ impl FolderListCommand { .and_then(ListFoldersMaildir::new) }); } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_list_folders(|ctx| ctx.imap.as_ref().and_then(ListFoldersImap::new)); - } _ => (), }, ) diff --git a/src/folder/command/mod.rs b/src/folder/command/mod.rs index ec2d54b..a8df793 100644 --- a/src/folder/command/mod.rs +++ b/src/folder/command/mod.rs @@ -1,7 +1,12 @@ +#[cfg(feature = "folder-add")] mod create; +#[cfg(feature = "folder-delete")] mod delete; +#[cfg(feature = "folder-expunge")] mod expunge; +#[cfg(feature = "folder-list")] mod list; +#[cfg(feature = "folder-purge")] mod purge; use anyhow::Result; @@ -9,10 +14,16 @@ use clap::Subcommand; use crate::{config::TomlConfig, printer::Printer}; -use self::{ - create::FolderCreateCommand, delete::FolderDeleteCommand, expunge::FolderExpungeCommand, - list::FolderListCommand, purge::FolderPurgeCommand, -}; +#[cfg(feature = "folder-add")] +use self::create::AddFolderCommand; +#[cfg(feature = "folder-delete")] +use self::delete::FolderDeleteCommand; +#[cfg(feature = "folder-expunge")] +use self::expunge::FolderExpungeCommand; +#[cfg(feature = "folder-list")] +use self::list::FolderListCommand; +#[cfg(feature = "folder-purge")] +use self::purge::FolderPurgeCommand; /// Manage folders. /// @@ -20,29 +31,40 @@ use self::{ /// emails. This subcommand allows you to manage them. #[derive(Debug, Subcommand)] pub enum FolderSubcommand { - #[command(alias = "add", alias = "new")] - Create(FolderCreateCommand), + #[cfg(feature = "folder-add")] + #[command(visible_alias = "create", alias = "new")] + Add(AddFolderCommand), + #[cfg(feature = "folder-list")] #[command(alias = "lst")] List(FolderListCommand), + #[cfg(feature = "folder-expunge")] #[command()] Expunge(FolderExpungeCommand), + #[cfg(feature = "folder-purge")] #[command()] Purge(FolderPurgeCommand), + #[cfg(feature = "folder-delete")] #[command(alias = "remove", alias = "rm")] Delete(FolderDeleteCommand), } impl FolderSubcommand { + #[allow(unused)] pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { match self { - Self::Create(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "folder-add")] + Self::Add(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "folder-list")] Self::List(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "folder-expunge")] Self::Expunge(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "folder-purge")] Self::Purge(cmd) => cmd.execute(printer, config).await, + #[cfg(feature = "folder-delete")] Self::Delete(cmd) => cmd.execute(printer, config).await, } } diff --git a/src/folder/command/purge.rs b/src/folder/command/purge.rs index a867c1b..c666f7d 100644 --- a/src/folder/command/purge.rs +++ b/src/folder/command/purge.rs @@ -6,13 +6,13 @@ use email::folder::purge::imap::PurgeFolderImap; use log::info; use std::process; +#[cfg(any(feature = "imap", feature = "maildir", feature = "sync"))] +use crate::backend::BackendKind; +#[cfg(feature = "sync")] +use crate::cache::arg::disable::CacheDisableFlag; use crate::{ - account::arg::name::AccountNameFlag, - backend::{Backend, BackendKind}, - cache::arg::disable::CacheDisableFlag, - config::TomlConfig, - folder::arg::name::FolderNameArg, - printer::Printer, + account::arg::name::AccountNameFlag, backend::Backend, config::TomlConfig, + folder::arg::name::FolderNameArg, printer::Printer, }; /// Purge a folder. @@ -24,6 +24,7 @@ pub struct FolderPurgeCommand { #[command(flatten)] pub folder: FolderNameArg, + #[cfg(feature = "sync")] #[command(flatten)] pub cache: CacheDisableFlag, @@ -49,6 +50,7 @@ impl FolderPurgeCommand { let (toml_account_config, account_config) = config.clone().into_account_configs( self.account.name.as_ref().map(String::as_str), + #[cfg(feature = "sync")] self.cache.disable, )?; @@ -59,12 +61,19 @@ impl FolderPurgeCommand { &account_config, purge_folder_kind, |builder| match purge_folder_kind { + #[cfg(feature = "imap")] + Some(BackendKind::Imap) => { + builder + .set_purge_folder(|ctx| ctx.imap.as_ref().and_then(PurgeFolderImap::new)); + } // TODO + // #[cfg(feature = "maildir")] // Some(BackendKind::Maildir) => { // builder.set_purge_folder(|ctx| { // ctx.maildir.as_ref().and_then(PurgeFolderMaildir::new) // }); // } + // #[cfg(feature = "sync")] // Some(BackendKind::MaildirForSync) => { // builder.set_purge_folder(|ctx| { // ctx.maildir_for_sync @@ -72,11 +81,6 @@ impl FolderPurgeCommand { // .and_then(PurgeFolderMaildir::new) // }); // } - #[cfg(feature = "imap")] - Some(BackendKind::Imap) => { - builder - .set_purge_folder(|ctx| ctx.imap.as_ref().and_then(PurgeFolderImap::new)); - } _ => (), }, ) diff --git a/src/folder/config.rs b/src/folder/config.rs index 5b1f3c3..e917672 100644 --- a/src/folder/config.rs +++ b/src/folder/config.rs @@ -8,33 +8,44 @@ pub struct FolderConfig { #[serde(alias = "aliases")] pub alias: Option>, + #[cfg(feature = "folder-add")] pub add: Option, + #[cfg(feature = "folder-list")] pub list: Option, + #[cfg(feature = "folder-expunge")] pub expunge: Option, + #[cfg(feature = "folder-purge")] pub purge: Option, + #[cfg(feature = "folder-delete")] pub delete: Option, } impl FolderConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { + #[allow(unused_mut)] let mut kinds = HashSet::default(); + #[cfg(feature = "folder-add")] if let Some(add) = &self.add { kinds.extend(add.get_used_backends()); } + #[cfg(feature = "folder-list")] if let Some(list) = &self.list { kinds.extend(list.get_used_backends()); } + #[cfg(feature = "folder-expunge")] if let Some(expunge) = &self.expunge { kinds.extend(expunge.get_used_backends()); } + #[cfg(feature = "folder-purge")] if let Some(purge) = &self.purge { kinds.extend(purge.get_used_backends()); } + #[cfg(feature = "folder-delete")] if let Some(delete) = &self.delete { kinds.extend(delete.get_used_backends()); } @@ -43,11 +54,13 @@ impl FolderConfig { } } +#[cfg(feature = "folder-add")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderAddConfig { pub backend: Option, } +#[cfg(feature = "folder-add")] impl FolderAddConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -60,6 +73,7 @@ impl FolderAddConfig { } } +#[cfg(feature = "folder-list")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderListConfig { pub backend: Option, @@ -68,6 +82,7 @@ pub struct FolderListConfig { pub remote: email::folder::list::config::FolderListConfig, } +#[cfg(feature = "folder-list")] impl FolderListConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -80,11 +95,13 @@ impl FolderListConfig { } } +#[cfg(feature = "folder-expunge")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderExpungeConfig { pub backend: Option, } +#[cfg(feature = "folder-expunge")] impl FolderExpungeConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -97,11 +114,13 @@ impl FolderExpungeConfig { } } +#[cfg(feature = "folder-purge")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderPurgeConfig { pub backend: Option, } +#[cfg(feature = "folder-purge")] impl FolderPurgeConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); @@ -114,11 +133,13 @@ impl FolderPurgeConfig { } } +#[cfg(feature = "folder-delete")] #[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] pub struct FolderDeleteConfig { pub backend: Option, } +#[cfg(feature = "folder-delete")] impl FolderDeleteConfig { pub fn get_used_backends(&self) -> HashSet<&BackendKind> { let mut kinds = HashSet::default(); diff --git a/src/folder/mod.rs b/src/folder/mod.rs index 577abab..4390e4e 100644 --- a/src/folder/mod.rs +++ b/src/folder/mod.rs @@ -1,22 +1,30 @@ +#[cfg(feature = "folder-command")] pub mod arg; +#[cfg(feature = "folder-command")] pub mod command; pub mod config; +#[cfg(feature = "folder-command")] use anyhow::Result; +#[cfg(feature = "folder-command")] use serde::Serialize; +#[cfg(feature = "folder-command")] use std::ops; +#[cfg(feature = "folder-command")] use crate::{ printer::{PrintTable, PrintTableOpts, WriteColor}, ui::{Cell, Row, Table}, }; +#[cfg(feature = "folder-command")] #[derive(Clone, Debug, Default, Serialize)] pub struct Folder { pub name: String, pub desc: String, } +#[cfg(feature = "folder-command")] impl From<&email::folder::Folder> for Folder { fn from(folder: &email::folder::Folder) -> Self { Folder { @@ -26,6 +34,7 @@ impl From<&email::folder::Folder> for Folder { } } +#[cfg(feature = "folder-command")] impl Table for Folder { fn head() -> Row { Row::new() @@ -40,9 +49,11 @@ impl Table for Folder { } } +#[cfg(feature = "folder-command")] #[derive(Clone, Debug, Default, Serialize)] pub struct Folders(Vec); +#[cfg(feature = "folder-command")] impl ops::Deref for Folders { type Target = Vec; @@ -51,12 +62,14 @@ impl ops::Deref for Folders { } } +#[cfg(feature = "folder-command")] impl From for Folders { fn from(folders: email::folder::Folders) -> Self { Folders(folders.iter().map(Folder::from).collect()) } } +#[cfg(feature = "folder-command")] impl PrintTable for Folders { fn print_table(&self, writer: &mut dyn WriteColor, opts: PrintTableOpts) -> Result<()> { writeln!(writer)?; diff --git a/src/main.rs b/src/main.rs index 328c144..881e2e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,14 @@ use anyhow::Result; use clap::Parser; use env_logger::{Builder as LoggerBuilder, Env, DEFAULT_FILTER_ENV}; -use himalaya::{ - cli::Cli, config::TomlConfig, envelope::command::list::ListEnvelopesCommand, - message::command::mailto::MessageMailtoCommand, printer::StdoutPrinter, -}; +#[cfg(any(feature = "envelope-list", feature = "message-mailto"))] +use himalaya::config::TomlConfig; +#[cfg(feature = "envelope-list")] +use himalaya::envelope::command::list::ListEnvelopesCommand; +#[cfg(feature = "message-mailto")] +use himalaya::message::command::mailto::MessageMailtoCommand; +use himalaya::{cli::Cli, printer::StdoutPrinter}; use log::{debug, warn}; -use std::env; #[tokio::main] async fn main() -> Result<()> { @@ -21,9 +23,13 @@ async fn main() -> Result<()> { .format_timestamp(None) .init(); + #[cfg(feature = "message-mailto")] // if the first argument starts by "mailto:", execute straight the // mailto message command - if let Some(ref url) = env::args().nth(1).filter(|arg| arg.starts_with("mailto:")) { + if let Some(ref url) = std::env::args() + .nth(1) + .filter(|arg| arg.starts_with("mailto:")) + { let mut printer = StdoutPrinter::default(); let config = TomlConfig::from_default_paths().await?; @@ -35,13 +41,20 @@ async fn main() -> Result<()> { let cli = Cli::parse(); let mut printer = StdoutPrinter::new(cli.output, cli.color); + #[cfg(feature = "envelope-list")] match cli.command { - Some(cmd) => cmd.execute(&mut printer, cli.config_path.as_ref()).await, + Some(cmd) => return cmd.execute(&mut printer, cli.config_path.as_ref()).await, None => { let config = TomlConfig::from_some_path_or_default(cli.config_path.as_ref()).await?; - ListEnvelopesCommand::default() + return ListEnvelopesCommand::default() .execute(&mut printer, &config) - .await + .await; } } + + #[cfg(not(feature = "envelope-list"))] + return cli + .command + .execute(&mut printer, cli.config_path.as_ref()) + .await; } diff --git a/src/ui/choice.rs b/src/ui/choice.rs index 1fb8993..ad0ce67 100644 --- a/src/ui/choice.rs +++ b/src/ui/choice.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Context, Result}; +use anyhow::{anyhow, bail, Context, Result}; use log::{debug, error}; use std::io::{self, Write}; @@ -43,9 +43,11 @@ pub fn pre_edit() -> Result { } pub enum PostEditChoice { + #[cfg(feature = "message-send")] Send, Edit, LocalDraft, + #[cfg(feature = "message-add")] RemoteDraft, Discard, } @@ -60,6 +62,7 @@ pub fn post_edit() -> Result { .context("cannot read stdin")?; match buf.bytes().next().map(|bytes| bytes as char) { + #[cfg(feature = "message-send")] Some('s') => { debug!("send choice matched"); Ok(PostEditChoice::Send) @@ -68,6 +71,7 @@ pub fn post_edit() -> Result { debug!("save local draft choice matched"); Ok(PostEditChoice::LocalDraft) } + #[cfg(feature = "message-add")] Some('r') => { debug!("save remote draft matched"); Ok(PostEditChoice::RemoteDraft) @@ -82,11 +86,11 @@ pub fn post_edit() -> Result { } Some(choice) => { error!(r#"invalid choice "{}""#, choice); - Err(anyhow!(r#"invalid choice "{}""#, choice)) + bail!("invalid choice {choice}"); } None => { error!("empty choice"); - Err(anyhow!("empty choice")) + bail!("empty choice"); } } } diff --git a/src/ui/editor.rs b/src/ui/editor.rs index 622a5ce..ef2ccb6 100644 --- a/src/ui/editor.rs +++ b/src/ui/editor.rs @@ -2,10 +2,14 @@ use anyhow::{Context, Result}; use email::{ account::config::AccountConfig, email::utils::{local_draft_path, remove_local_draft}, +}; +#[cfg(feature = "message-add")] +use email::{ flag::{Flag, Flags}, folder::DRAFTS, }; use log::debug; +#[cfg(any(feature = "message-send", feature = "template-send"))] use mml::MmlCompilerBuilder; use process::SingleCmd; use std::{env, fs}; @@ -44,8 +48,9 @@ pub async fn open_with_local_draft() -> Result { open_with_tpl(content).await } +#[allow(unused)] pub async fn edit_tpl_with_editor( - #[allow(unused)] config: &AccountConfig, + config: &AccountConfig, printer: &mut P, backend: &Backend, mut tpl: String, @@ -77,6 +82,7 @@ pub async fn edit_tpl_with_editor( loop { match choice::post_edit() { + #[cfg(feature = "message-send")] Ok(PostEditChoice::Send) => { printer.print_log("Sending email…")?; @@ -88,7 +94,7 @@ pub async fn edit_tpl_with_editor( let email = compiler.build(tpl.as_str())?.compile().await?.into_vec()?; - backend.send_raw_message(&email).await?; + backend.send_message(&email).await?; remove_local_draft()?; printer.print("Done!")?; @@ -102,6 +108,7 @@ pub async fn edit_tpl_with_editor( printer.print("Email successfully saved locally")?; break; } + #[cfg(feature = "message-add")] Ok(PostEditChoice::RemoteDraft) => { #[allow(unused_mut)] let mut compiler = MmlCompilerBuilder::new(); @@ -112,7 +119,7 @@ pub async fn edit_tpl_with_editor( let email = compiler.build(tpl.as_str())?.compile().await?.into_vec()?; backend - .add_raw_message_with_flags( + .add_message_with_flags( DRAFTS, &email, &Flags::from_iter([Flag::Seen, Flag::Draft]),