improve backend features management for every command

This commit is contained in:
Clément DOUIN 2024-01-03 12:58:44 +01:00
parent a8c6756f56
commit 0352e91e36
No known key found for this signature in database
GPG key ID: 353E4A18EE0FAB72
29 changed files with 1290 additions and 371 deletions

View file

@ -101,7 +101,7 @@ impl AccountSyncCommand {
let account_name = account_config.name.as_str(); let account_name = account_config.name.as_str();
let backend_builder = let backend_builder =
BackendBuilder::new(toml_account_config, account_config.clone(), false).await?; BackendBuilder::new(toml_account_config, account_config.clone()).await?;
let sync_builder = AccountSyncBuilder::new(backend_builder.into()) let sync_builder = AccountSyncBuilder::new(backend_builder.into())
.await? .await?
.with_some_folders_strategy(strategy) .with_some_folders_strategy(strategy)

View file

@ -111,6 +111,14 @@ impl TomlAccountConfig {
.or_else(|| self.backend.as_ref()) .or_else(|| self.backend.as_ref())
} }
pub fn watch_envelopes_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 add_flags_kind(&self) -> Option<&BackendKind> { pub fn add_flags_kind(&self) -> Option<&BackendKind> {
self.flag self.flag
.as_ref() .as_ref()

View file

@ -40,7 +40,6 @@ use email::{
get::imap::GetMessagesImap, get::imap::GetMessagesImap,
move_::{imap::MoveMessagesImap, maildir::MoveMessagesMaildir}, move_::{imap::MoveMessagesImap, maildir::MoveMessagesMaildir},
peek::{imap::PeekMessagesImap, maildir::PeekMessagesMaildir}, peek::{imap::PeekMessagesImap, maildir::PeekMessagesMaildir},
send_raw::{sendmail::SendRawMessageSendmail, smtp::SendRawMessageSmtp},
Messages, Messages,
}, },
sendmail::SendmailContext, sendmail::SendmailContext,
@ -93,6 +92,68 @@ pub struct BackendContextBuilder {
pub sendmail: Option<SendmailContext>, pub sendmail: Option<SendmailContext>,
} }
impl BackendContextBuilder {
pub async fn new(
toml_account_config: &TomlAccountConfig,
account_config: &AccountConfig,
kinds: Vec<&BackendKind>,
) -> Result<Self> {
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
.imap
.as_ref()
.filter(|_| kinds.contains(&&BackendKind::Imap))
.map(|imap_config| {
ImapSessionBuilder::new(account_config.clone(), imap_config.clone())
.with_prebuilt_credentials()
});
match ctx_builder {
Some(ctx_builder) => Some(ctx_builder.await?),
None => None,
}
},
#[cfg(feature = "notmuch")]
notmuch: toml_account_config
.notmuch
.as_ref()
.filter(|_| kinds.contains(&&BackendKind::Notmuch))
.map(|notmuch_config| {
NotmuchSessionBuilder::new(account_config.clone(), notmuch_config.clone())
}),
#[cfg(feature = "smtp")]
smtp: toml_account_config
.smtp
.as_ref()
.filter(|_| kinds.contains(&&BackendKind::Smtp))
.map(|smtp_config| {
SmtpClientBuilder::new(account_config.clone(), smtp_config.clone())
}),
#[cfg(feature = "sendmail")]
sendmail: toml_account_config
.sendmail
.as_ref()
.filter(|_| kinds.contains(&&BackendKind::Sendmail))
.map(|sendmail_config| {
SendmailContext::new(account_config.clone(), sendmail_config.clone())
}),
})
}
}
#[async_trait] #[async_trait]
impl email::backend::BackendContextBuilder for BackendContextBuilder { impl email::backend::BackendContextBuilder for BackendContextBuilder {
type Context = BackendContext; type Context = BackendContext;
@ -151,7 +212,6 @@ impl BackendBuilder {
pub async fn new( pub async fn new(
toml_account_config: TomlAccountConfig, toml_account_config: TomlAccountConfig,
account_config: AccountConfig, account_config: AccountConfig,
with_sending: bool,
) -> Result<Self> { ) -> Result<Self> {
let used_backends = toml_account_config.get_used_backends(); let used_backends = toml_account_config.get_used_backends();
@ -159,11 +219,6 @@ impl BackendBuilder {
let is_maildir_for_sync_used = used_backends.contains(&BackendKind::MaildirForSync); let is_maildir_for_sync_used = used_backends.contains(&BackendKind::MaildirForSync);
#[cfg(feature = "imap")] #[cfg(feature = "imap")]
let is_imap_used = used_backends.contains(&BackendKind::Imap); let is_imap_used = used_backends.contains(&BackendKind::Imap);
#[cfg(feature = "notmuch")]
let is_notmuch_used = used_backends.contains(&BackendKind::Notmuch);
#[cfg(feature = "smtp")]
let is_smtp_used = used_backends.contains(&BackendKind::Smtp);
let is_sendmail_used = used_backends.contains(&BackendKind::Sendmail);
let backend_ctx_builder = BackendContextBuilder { let backend_ctx_builder = BackendContextBuilder {
maildir: toml_account_config maildir: toml_account_config
@ -195,31 +250,7 @@ impl BackendBuilder {
None => None, None => None,
} }
}, },
#[cfg(feature = "notmuch")] ..Default::default()
notmuch: toml_account_config
.notmuch
.as_ref()
.filter(|_| is_notmuch_used)
.map(|notmuch_config| {
NotmuchSessionBuilder::new(account_config.clone(), notmuch_config.clone())
}),
#[cfg(feature = "smtp")]
smtp: toml_account_config
.smtp
.as_ref()
.filter(|_| with_sending)
.filter(|_| is_smtp_used)
.map(|smtp_config| {
SmtpClientBuilder::new(account_config.clone(), smtp_config.clone())
}),
sendmail: toml_account_config
.sendmail
.as_ref()
.filter(|_| with_sending)
.filter(|_| is_sendmail_used)
.map(|sendmail_config| {
SendmailContext::new(account_config.clone(), sendmail_config.clone())
}),
}; };
let mut backend_builder = let mut backend_builder =
@ -511,21 +542,6 @@ impl BackendBuilder {
_ => (), _ => (),
} }
match toml_account_config.send_raw_message_kind() {
#[cfg(feature = "smtp")]
Some(BackendKind::Smtp) => {
backend_builder = backend_builder.with_send_raw_message(|ctx| {
ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new)
});
}
Some(BackendKind::Sendmail) => {
backend_builder = backend_builder.with_send_raw_message(|ctx| {
ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new)
});
}
_ => (),
}
match toml_account_config.add_raw_message_kind() { match toml_account_config.add_raw_message_kind() {
Some(BackendKind::Maildir) => { Some(BackendKind::Maildir) => {
backend_builder = backend_builder.with_add_raw_message_with_flags(|ctx| { backend_builder = backend_builder.with_add_raw_message_with_flags(|ctx| {
@ -689,23 +705,22 @@ pub struct Backend {
impl Backend { impl Backend {
pub async fn new( pub async fn new(
toml_account_config: TomlAccountConfig, toml_account_config: &TomlAccountConfig,
account_config: AccountConfig, account_config: &AccountConfig,
with_sending: bool, backend_kinds: impl IntoIterator<Item = &BackendKind>,
with_features: impl Fn(&mut email::backend::BackendBuilder<BackendContextBuilder>),
) -> Result<Self> { ) -> Result<Self> {
BackendBuilder::new(toml_account_config, account_config, with_sending) let backend_kinds = backend_kinds.into_iter().collect();
.await? let backend_ctx_builder =
.build() BackendContextBuilder::new(toml_account_config, account_config, backend_kinds).await?;
.await let mut backend_builder =
} email::backend::BackendBuilder::new(account_config.clone(), backend_ctx_builder);
with_features(&mut backend_builder);
pub async fn new_v2(
toml_account_config: TomlAccountConfig,
builder: email::backend::BackendBuilder<BackendContextBuilder>,
) -> Result<Self> {
Ok(Self { Ok(Self {
toml_account_config, toml_account_config: toml_account_config.clone(),
backend: builder.build().await?, backend: backend_builder.build().await?,
}) })
} }

View file

@ -1,18 +1,16 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
use email::backend::BackendBuilder;
#[cfg(feature = "imap")] #[cfg(feature = "imap")]
use email::{envelope::list::imap::ListEnvelopesImap, imap::ImapSessionBuilder}; use email::envelope::list::imap::ListEnvelopesImap;
#[cfg(feature = "maildir")] #[cfg(feature = "maildir")]
use email::{ use email::envelope::list::maildir::ListEnvelopesMaildir;
envelope::list::maildir::ListEnvelopesMaildir, #[cfg(feature = "notmuch")]
maildir::{config::MaildirConfig, MaildirSessionBuilder}, use email::envelope::list::notmuch::ListEnvelopesNotmuch;
};
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::{Backend, BackendContextBuilder, BackendKind}, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
folder::arg::name::FolderNameOptionalArg, folder::arg::name::FolderNameOptionalArg,
@ -54,90 +52,48 @@ pub struct ListEnvelopesCommand {
impl ListEnvelopesCommand { impl ListEnvelopesCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing envelope list command"); info!("executing list envelopes command");
let (toml_account_config, account_config) = config.clone().into_account_configs(
self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let folder = &self.folder.name; let folder = &self.folder.name;
let page = 1.max(self.page) - 1;
let some_account_name = self.account.name.as_ref().map(String::as_str);
let (toml_account_config, account_config) = config
.clone()
.into_account_configs(some_account_name, self.cache.disable)?;
let backend_kind = toml_account_config.list_envelopes_kind();
let backend_ctx_builder = BackendContextBuilder {
maildir: toml_account_config
.maildir
.as_ref()
.filter(|_| matches!(backend_kind, Some(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(|_| matches!(backend_kind, Some(BackendKind::MaildirForSync)))
.map(|mdir_config| MaildirSessionBuilder::new(account_config.clone(), mdir_config)),
#[cfg(feature = "imap")]
imap: {
let ctx_builder = toml_account_config
.imap
.as_ref()
.filter(|_| matches!(backend_kind, Some(BackendKind::Imap)))
.map(|imap_config| {
ImapSessionBuilder::new(account_config.clone(), imap_config.clone())
.with_prebuilt_credentials()
});
match ctx_builder {
Some(ctx_builder) => Some(ctx_builder.await?),
None => None,
}
},
#[cfg(feature = "notmuch")]
notmuch: toml_account_config
.notmuch
.as_ref()
.filter(|_| matches!(backend_kind, Some(BackendKind::Notmuch)))
.map(|notmuch_config| {
NotmuchSessionBuilder::new(account_config.clone(), notmuch_config.clone())
}),
..Default::default()
};
let mut backend_builder = BackendBuilder::new(account_config.clone(), backend_ctx_builder);
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)
});
}
_ => (),
}
let backend = Backend::new_v2(toml_account_config.clone(), backend_builder).await?;
let page_size = self let page_size = self
.page_size .page_size
.unwrap_or(account_config.get_envelope_list_page_size()); .unwrap_or_else(|| account_config.get_envelope_list_page_size());
let page = 1.max(self.page) - 1;
let list_envelopes_kind = toml_account_config.list_envelopes_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
list_envelopes_kind,
|builder| match list_envelopes_kind {
Some(BackendKind::Maildir) => {
builder.set_list_envelopes(|ctx| {
ctx.maildir.as_ref().and_then(ListEnvelopesMaildir::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_list_envelopes(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(ListEnvelopesMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder.set_list_envelopes(|ctx| {
ctx.imap.as_ref().and_then(ListEnvelopesImap::new)
});
}
_ => (),
},
)
.await?;
let envelopes = backend.list_envelopes(folder, page_size, page).await?; let envelopes = backend.list_envelopes(folder, page_size, page).await?;

View file

@ -1,10 +1,20 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::envelope::watch::imap::WatchImapEnvelopes;
#[cfg(feature = "maildir")]
use email::envelope::watch::maildir::WatchMaildirEnvelopes;
#[cfg(feature = "notmuch")]
use email::envelope::watch::notmuch::WatchNotmuchEnvelopes;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, folder::arg::name::FolderNameOptionalFlag, printer::Printer, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
}; };
/// Watch envelopes for changes. /// Watch envelopes for changes.
@ -25,15 +35,43 @@ pub struct WatchEnvelopesCommand {
impl WatchEnvelopesCommand { impl WatchEnvelopesCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing envelopes watch command"); info!("executing watch envelopes command");
let folder = &self.folder.name; 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),
self.cache.disable,
)?;
let some_account_name = self.account.name.as_ref().map(String::as_str); let watch_envelopes_kind = toml_account_config.watch_envelopes_kind();
let (toml_account_config, account_config) = config
.clone() let backend = Backend::new(
.into_account_configs(some_account_name, self.cache.disable)?; &toml_account_config,
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; &account_config,
watch_envelopes_kind,
|builder| match watch_envelopes_kind {
Some(BackendKind::Maildir) => {
builder.set_watch_envelopes(|ctx| {
ctx.maildir.as_ref().and_then(WatchMaildirEnvelopes::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_watch_envelopes(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(WatchMaildirEnvelopes::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder.set_watch_envelopes(|ctx| {
ctx.imap.as_ref().and_then(WatchImapEnvelopes::new)
});
}
_ => (),
},
)
.await?;
printer.print_log(format!( printer.print_log(format!(
"Start watching folder {folder} for envelopes changes…" "Start watching folder {folder} for envelopes changes…"

View file

@ -1,10 +1,16 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::flag::add::imap::AddFlagsImap;
#[cfg(feature = "maildir")]
use email::flag::add::maildir::AddFlagsMaildir;
#[cfg(feature = "notmuch")]
use email::flag::add::notmuch::AddFlagsNotmuch;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs}, flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
@ -33,17 +39,40 @@ pub struct FlagAddCommand {
impl FlagAddCommand { impl FlagAddCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing flag add command"); info!("executing add flag(s) command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let (ids, flags) = into_tuple(&self.args.ids_and_flags); 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),
self.cache.disable,
)?;
let add_flags_kind = toml_account_config.add_flags_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
add_flags_kind,
|builder| match add_flags_kind {
Some(BackendKind::Maildir) => {
builder
.set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new));
}
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));
}
_ => (),
},
)
.await?;
backend.add_flags(folder, &ids, &flags).await?; backend.add_flags(folder, &ids, &flags).await?;
printer.print(format!("Flag(s) {flags} successfully added!")) printer.print(format!("Flag(s) {flags} successfully added!"))

View file

@ -1,10 +1,16 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::flag::remove::imap::RemoveFlagsImap;
#[cfg(feature = "maildir")]
use email::flag::remove::maildir::RemoveFlagsMaildir;
#[cfg(feature = "notmuch")]
use email::flag::remove::notmuch::RemoveFlagsNotmuch;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs}, flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
@ -33,17 +39,44 @@ pub struct FlagRemoveCommand {
impl FlagRemoveCommand { impl FlagRemoveCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing flag remove command"); info!("executing remove flag(s) command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let (ids, flags) = into_tuple(&self.args.ids_and_flags); 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),
self.cache.disable,
)?;
let remove_flags_kind = toml_account_config.remove_flags_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
remove_flags_kind,
|builder| match remove_flags_kind {
Some(BackendKind::Maildir) => {
builder.set_remove_flags(|ctx| {
ctx.maildir.as_ref().and_then(RemoveFlagsMaildir::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_remove_flags(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(RemoveFlagsMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder
.set_remove_flags(|ctx| ctx.imap.as_ref().and_then(RemoveFlagsImap::new));
}
_ => (),
},
)
.await?;
backend.remove_flags(folder, &ids, &flags).await?; backend.remove_flags(folder, &ids, &flags).await?;
printer.print(format!("Flag(s) {flags} successfully removed!")) printer.print(format!("Flag(s) {flags} successfully removed!"))

View file

@ -1,10 +1,16 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::flag::set::imap::SetFlagsImap;
#[cfg(feature = "maildir")]
use email::flag::set::maildir::SetFlagsMaildir;
#[cfg(feature = "notmuch")]
use email::flag::set::notmuch::SetFlagsNotmuch;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs}, flag::arg::ids_and_flags::{into_tuple, IdsAndFlagsArgs},
@ -33,19 +39,42 @@ pub struct FlagSetCommand {
impl FlagSetCommand { impl FlagSetCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing flag set command"); info!("executing set flag(s) command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let (ids, flags) = into_tuple(&self.args.ids_and_flags); 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),
self.cache.disable,
)?;
let set_flags_kind = toml_account_config.set_flags_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
set_flags_kind,
|builder| match set_flags_kind {
Some(BackendKind::Maildir) => {
builder
.set_set_flags(|ctx| ctx.maildir.as_ref().and_then(SetFlagsMaildir::new));
}
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));
}
_ => (),
},
)
.await?;
backend.set_flags(folder, &ids, &flags).await?; backend.set_flags(folder, &ids, &flags).await?;
printer.print(format!("Flag(s) {flags} successfully set!")) printer.print(format!("Flag(s) {flags} successfully replaced!"))
} }
} }

View file

@ -1,13 +1,21 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::{get::imap::GetMessagesImap, peek::imap::PeekMessagesImap};
#[cfg(feature = "maildir")]
use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMessagesMaildir};
use log::info; use log::info;
use std::{fs, path::PathBuf}; use std::{fs, path::PathBuf};
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, backend::{Backend, BackendKind},
folder::arg::name::FolderNameOptionalFlag, printer::Printer, cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
}; };
/// Download all attachments for the given message. /// Download all attachments for the given message.
@ -31,17 +39,52 @@ pub struct AttachmentDownloadCommand {
impl AttachmentDownloadCommand { impl AttachmentDownloadCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing attachment download command"); info!("executing download attachment(s) command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let ids = &self.envelopes.ids; let ids = &self.envelopes.ids;
let (toml_account_config, account_config) = config.clone().into_account_configs(
self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let get_messages_kind = toml_account_config.get_messages_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
get_messages_kind,
|builder| match get_messages_kind {
Some(BackendKind::Maildir) => {
builder.set_peek_messages(|ctx| {
ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new)
});
builder
.set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new));
}
Some(BackendKind::MaildirForSync) => {
builder.set_peek_messages(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(PeekMessagesMaildir::new)
});
builder.set_add_flags(|ctx| {
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));
}
_ => (),
},
)
.await?;
let emails = backend.get_messages(&folder, ids).await?; let emails = backend.get_messages(&folder, ids).await?;
let mut emails_count = 0; let mut emails_count = 0;

View file

@ -1,10 +1,14 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::copy::imap::CopyMessagesImap;
#[cfg(feature = "maildir")]
use email::message::copy::maildir::CopyMessagesMaildir;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
envelope::arg::ids::EnvelopeIdsArgs, envelope::arg::ids::EnvelopeIdsArgs,
@ -33,22 +37,50 @@ pub struct MessageCopyCommand {
impl MessageCopyCommand { impl MessageCopyCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message copy command"); info!("executing copy message(s) command");
let from_folder = &self.source_folder.name;
let to_folder = &self.target_folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let source = &self.source_folder.name;
let target = &self.target_folder.name;
let ids = &self.envelopes.ids; let ids = &self.envelopes.ids;
backend.copy_messages(from_folder, to_folder, ids).await?;
let (toml_account_config, account_config) = config.clone().into_account_configs(
self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let copy_messages_kind = toml_account_config.copy_messages_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
copy_messages_kind,
|builder| match copy_messages_kind {
Some(BackendKind::Maildir) => {
builder.set_copy_messages(|ctx| {
ctx.maildir.as_ref().and_then(CopyMessagesMaildir::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_copy_messages(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(CopyMessagesMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder
.set_copy_messages(|ctx| ctx.imap.as_ref().and_then(CopyMessagesImap::new));
}
_ => (),
},
)
.await?;
backend.copy_messages(source, target, ids).await?;
printer.print(format!( printer.print(format!(
"Message(s) successfully copied from {from_folder} to {to_folder}!" "Message(s) successfully copied from {source} to {target}!"
)) ))
} }
} }

View file

@ -1,11 +1,19 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::{flag::add::imap::AddFlagsImap, message::move_::imap::MoveMessagesImap};
#[cfg(feature = "maildir")]
use email::{flag::add::maildir::AddFlagsMaildir, message::move_::maildir::MoveMessagesMaildir};
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, backend::{Backend, BackendKind},
folder::arg::name::FolderNameOptionalFlag, printer::Printer, cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
}; };
/// Mark as deleted a message from a folder. /// Mark as deleted a message from a folder.
@ -31,17 +39,51 @@ pub struct MessageDeleteCommand {
impl MessageDeleteCommand { impl MessageDeleteCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message delete command"); info!("executing delete message(s) command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let ids = &self.envelopes.ids; let ids = &self.envelopes.ids;
let (toml_account_config, account_config) = config.clone().into_account_configs(
self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let delete_messages_kind = toml_account_config.delete_messages_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
delete_messages_kind,
|builder| match delete_messages_kind {
Some(BackendKind::Maildir) => {
builder.set_move_messages(|ctx| {
ctx.maildir.as_ref().and_then(MoveMessagesMaildir::new)
});
builder
.set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new));
}
Some(BackendKind::MaildirForSync) => {
builder.set_move_messages(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(MoveMessagesMaildir::new)
});
builder.set_add_flags(|ctx| {
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));
}
_ => (),
},
)
.await?;
backend.delete_messages(folder, ids).await?; backend.delete_messages(folder, ids).await?;
printer.print(format!("Message(s) successfully removed from {folder}!")) printer.print(format!("Message(s) successfully removed from {folder}!"))

View file

@ -1,10 +1,18 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::add_raw::imap::AddRawMessageImap;
#[cfg(feature = "maildir")]
use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir;
#[cfg(feature = "sendmail")]
use email::message::send_raw::sendmail::SendRawMessageSendmail;
#[cfg(feature = "smtp")]
use email::message::send_raw::smtp::SendRawMessageSmtp;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
envelope::arg::ids::EnvelopeIdArg, envelope::arg::ids::EnvelopeIdArg,
@ -43,15 +51,65 @@ pub struct MessageForwardCommand {
impl MessageForwardCommand { impl MessageForwardCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message forward command"); info!("executing forward message command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) = let (toml_account_config, account_config) = config.clone().into_account_configs(
config.clone().into_account_configs(account, cache)?; self.account.name.as_ref().map(String::as_str),
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; 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 backend = Backend::new(
&toml_account_config,
&account_config,
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)
});
}
_ => (),
};
match send_message_kind {
#[cfg(feature = "smtp")]
Some(BackendKind::Smtp) => {
builder.set_send_raw_message(|ctx| {
ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new)
});
}
#[cfg(feature = "sendmail")]
Some(BackendKind::Sendmail) => {
builder.set_send_raw_message(|ctx| {
ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new)
});
}
_ => (),
};
},
)
.await?;
let id = self.envelope.id; let id = self.envelope.id;
let tpl = backend let tpl = backend

View file

@ -1,12 +1,24 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::add_raw::imap::AddRawMessageImap;
#[cfg(feature = "maildir")]
use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir;
#[cfg(feature = "sendmail")]
use email::message::send_raw::sendmail::SendRawMessageSendmail;
#[cfg(feature = "smtp")]
use email::message::send_raw::smtp::SendRawMessageSmtp;
use log::{debug, info}; use log::{debug, info};
use mail_builder::MessageBuilder; use mail_builder::MessageBuilder;
use url::Url; use url::Url;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, printer::Printer, ui::editor, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
printer::Printer,
ui::editor,
}; };
/// Parse and edit a message from a mailto URL string. /// Parse and edit a message from a mailto URL string.
@ -38,14 +50,63 @@ impl MessageMailtoCommand {
} }
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message mailto command"); info!("executing mailto message command");
let account = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let cache = self.cache.disable; self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let (toml_account_config, account_config) = let add_message_kind = toml_account_config.add_raw_message_kind();
config.clone().into_account_configs(account, cache)?; let send_message_kind = toml_account_config.send_raw_message_kind();
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;
let backend = Backend::new(
&toml_account_config,
&account_config,
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)
});
}
_ => (),
};
match send_message_kind {
#[cfg(feature = "smtp")]
Some(BackendKind::Smtp) => {
builder.set_send_raw_message(|ctx| {
ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new)
});
}
#[cfg(feature = "sendmail")]
Some(BackendKind::Sendmail) => {
builder.set_send_raw_message(|ctx| {
ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new)
});
}
_ => (),
};
},
)
.await?;
let mut builder = MessageBuilder::new().to(self.url.path()); let mut builder = MessageBuilder::new().to(self.url.path());
let mut body = String::new(); let mut body = String::new();

View file

@ -1,10 +1,14 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::move_::imap::MoveMessagesImap;
#[cfg(feature = "maildir")]
use email::message::move_::maildir::MoveMessagesMaildir;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
envelope::arg::ids::EnvelopeIdsArgs, envelope::arg::ids::EnvelopeIdsArgs,
@ -33,22 +37,50 @@ pub struct MessageMoveCommand {
impl MessageMoveCommand { impl MessageMoveCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message move command"); info!("executing move message(s) command");
let from_folder = &self.source_folder.name;
let to_folder = &self.target_folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let source = &self.source_folder.name;
let target = &self.target_folder.name;
let ids = &self.envelopes.ids; let ids = &self.envelopes.ids;
backend.move_messages(from_folder, to_folder, ids).await?;
let (toml_account_config, account_config) = config.clone().into_account_configs(
self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let move_messages_kind = toml_account_config.move_messages_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
move_messages_kind,
|builder| match move_messages_kind {
Some(BackendKind::Maildir) => {
builder.set_move_messages(|ctx| {
ctx.maildir.as_ref().and_then(MoveMessagesMaildir::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_move_messages(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(MoveMessagesMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder
.set_move_messages(|ctx| ctx.imap.as_ref().and_then(MoveMessagesImap::new));
}
_ => (),
},
)
.await?;
backend.move_messages(source, target, ids).await?;
printer.print(format!( printer.print(format!(
"Message(s) successfully moved from {from_folder} to {to_folder}!" "Message(s) successfully moved from {source} to {target}!"
)) ))
} }
} }

View file

@ -1,12 +1,20 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::{get::imap::GetMessagesImap, peek::imap::PeekMessagesImap};
#[cfg(feature = "maildir")]
use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMessagesMaildir};
use log::info; use log::info;
use mml::message::FilterParts; use mml::message::FilterParts;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, envelope::arg::ids::EnvelopeIdsArgs, backend::{Backend, BackendKind},
folder::arg::name::FolderNameOptionalFlag, printer::Printer, cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
envelope::arg::ids::EnvelopeIdsArgs,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
}; };
/// Read a message. /// Read a message.
@ -75,17 +83,52 @@ pub struct MessageReadCommand {
impl MessageReadCommand { impl MessageReadCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message read command"); info!("executing read message(s) command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) =
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let ids = &self.envelopes.ids; let ids = &self.envelopes.ids;
let (toml_account_config, account_config) = config.clone().into_account_configs(
self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let get_messages_kind = toml_account_config.get_messages_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
get_messages_kind,
|builder| match get_messages_kind {
Some(BackendKind::Maildir) => {
builder.set_peek_messages(|ctx| {
ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new)
});
builder
.set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new));
}
Some(BackendKind::MaildirForSync) => {
builder.set_peek_messages(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(PeekMessagesMaildir::new)
});
builder.set_add_flags(|ctx| {
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));
}
_ => (),
},
)
.await?;
let emails = if self.preview { let emails = if self.preview {
backend.peek_messages(&folder, &ids).await backend.peek_messages(&folder, &ids).await
} else { } else {

View file

@ -1,11 +1,19 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::Parser; use clap::Parser;
use email::flag::Flag; use email::flag::Flag;
#[cfg(feature = "imap")]
use email::message::add_raw::imap::AddRawMessageImap;
#[cfg(feature = "maildir")]
use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir;
#[cfg(feature = "sendmail")]
use email::message::send_raw::sendmail::SendRawMessageSendmail;
#[cfg(feature = "smtp")]
use email::message::send_raw::smtp::SendRawMessageSmtp;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
envelope::arg::ids::EnvelopeIdArg, envelope::arg::ids::EnvelopeIdArg,
@ -47,15 +55,64 @@ pub struct MessageReplyCommand {
impl MessageReplyCommand { impl MessageReplyCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message reply command"); info!("executing reply message command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let cache = self.cache.disable; self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let (toml_account_config, account_config) = let add_message_kind = toml_account_config.add_raw_message_kind();
config.clone().into_account_configs(account, cache)?; let send_message_kind = toml_account_config.send_raw_message_kind();
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;
let backend = Backend::new(
&toml_account_config,
&account_config,
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)
});
}
_ => (),
};
match send_message_kind {
#[cfg(feature = "smtp")]
Some(BackendKind::Smtp) => {
builder.set_send_raw_message(|ctx| {
ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new)
});
}
#[cfg(feature = "sendmail")]
Some(BackendKind::Sendmail) => {
builder.set_send_raw_message(|ctx| {
ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new)
});
}
_ => (),
};
},
)
.await?;
let id = self.envelope.id; let id = self.envelope.id;
let tpl = backend let tpl = backend

View file

@ -1,11 +1,19 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::add_raw::imap::AddRawMessageImap;
#[cfg(feature = "maildir")]
use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir;
use log::info; use log::info;
use std::io::{self, BufRead, IsTerminal}; use std::io::{self, BufRead, IsTerminal};
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, folder::arg::name::FolderNameOptionalFlag, message::arg::MessageRawArg, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
folder::arg::name::FolderNameOptionalFlag,
message::arg::MessageRawArg,
printer::Printer, printer::Printer,
}; };
@ -29,15 +37,46 @@ pub struct MessageSaveCommand {
impl MessageSaveCommand { impl MessageSaveCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message save command"); info!("executing save message command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) = let (toml_account_config, account_config) = config.clone().into_account_configs(
config.clone().into_account_configs(account, cache)?; self.account.name.as_ref().map(String::as_str),
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; self.cache.disable,
)?;
let add_message_kind = toml_account_config.add_raw_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)
});
}
_ => (),
},
)
.await?;
let is_tty = io::stdin().is_terminal(); let is_tty = io::stdin().is_terminal();
let is_json = printer.is_json(); let is_json = printer.is_json();

View file

@ -1,11 +1,19 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "sendmail")]
use email::message::send_raw::sendmail::SendRawMessageSendmail;
#[cfg(feature = "smtp")]
use email::message::send_raw::smtp::SendRawMessageSmtp;
use log::info; use log::info;
use std::io::{self, BufRead, IsTerminal}; use std::io::{self, BufRead, IsTerminal};
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, message::arg::MessageRawArg, printer::Printer, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
message::arg::MessageRawArg,
printer::Printer,
}; };
/// Send a message. /// Send a message.
@ -26,14 +34,38 @@ pub struct MessageSendCommand {
impl MessageSendCommand { impl MessageSendCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message send command"); info!("executing send message command");
let account = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let cache = self.cache.disable; self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let (toml_account_config, account_config) = let send_message_kind = toml_account_config.send_raw_message_kind();
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; let backend = Backend::new(
&toml_account_config,
&account_config,
send_message_kind,
|builder| {
match send_message_kind {
#[cfg(feature = "smtp")]
Some(BackendKind::Smtp) => {
builder.set_send_raw_message(|ctx| {
ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new)
});
}
#[cfg(feature = "sendmail")]
Some(BackendKind::Sendmail) => {
builder.set_send_raw_message(|ctx| {
ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new)
});
}
_ => (),
};
},
)
.await?;
let msg = if io::stdin().is_terminal() { let msg = if io::stdin().is_terminal() {
self.message.raw() self.message.raw()

View file

@ -1,11 +1,19 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::add_raw::imap::AddRawMessageImap;
#[cfg(feature = "maildir")]
use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir;
#[cfg(feature = "sendmail")]
use email::message::send_raw::sendmail::SendRawMessageSendmail;
#[cfg(feature = "smtp")]
use email::message::send_raw::smtp::SendRawMessageSmtp;
use email::message::Message; use email::message::Message;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs}, message::arg::{body::MessageRawBodyArg, header::HeaderRawArgs},
@ -36,14 +44,63 @@ pub struct MessageWriteCommand {
impl MessageWriteCommand { impl MessageWriteCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing message write command"); info!("executing write message command");
let account = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let cache = self.cache.disable; self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let (toml_account_config, account_config) = let add_message_kind = toml_account_config.add_raw_message_kind();
config.clone().into_account_configs(account, cache)?; let send_message_kind = toml_account_config.send_raw_message_kind();
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?;
let backend = Backend::new(
&toml_account_config,
&account_config,
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)
});
}
_ => (),
};
match send_message_kind {
#[cfg(feature = "smtp")]
Some(BackendKind::Smtp) => {
builder.set_send_raw_message(|ctx| {
ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new)
});
}
#[cfg(feature = "sendmail")]
Some(BackendKind::Sendmail) => {
builder.set_send_raw_message(|ctx| {
ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new)
});
}
_ => (),
};
},
)
.await?;
let tpl = Message::new_tpl_builder(&account_config) let tpl = Message::new_tpl_builder(&account_config)
.with_headers(self.headers.raw) .with_headers(self.headers.raw)

View file

@ -1,10 +1,14 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::{get::imap::GetMessagesImap, peek::imap::PeekMessagesImap};
#[cfg(feature = "maildir")]
use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMessagesMaildir};
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
envelope::arg::ids::EnvelopeIdArg, envelope::arg::ids::EnvelopeIdArg,
@ -44,12 +48,47 @@ impl TemplateForwardCommand {
info!("executing template forward command"); info!("executing template forward command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) = let (toml_account_config, account_config) = config.clone().into_account_configs(
config.clone().into_account_configs(account, cache)?; self.account.name.as_ref().map(String::as_str),
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; self.cache.disable,
)?;
let get_messages_kind = toml_account_config.get_messages_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
get_messages_kind,
|builder| match get_messages_kind {
Some(BackendKind::Maildir) => {
builder.set_peek_messages(|ctx| {
ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new)
});
builder
.set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new));
}
Some(BackendKind::MaildirForSync) => {
builder.set_peek_messages(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(PeekMessagesMaildir::new)
});
builder.set_add_flags(|ctx| {
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));
}
_ => (),
},
)
.await?;
let id = self.envelope.id; let id = self.envelope.id;
let tpl: String = backend let tpl: String = backend

View file

@ -1,10 +1,14 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::{get::imap::GetMessagesImap, peek::imap::PeekMessagesImap};
#[cfg(feature = "maildir")]
use email::{flag::add::maildir::AddFlagsMaildir, message::peek::maildir::PeekMessagesMaildir};
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
envelope::arg::ids::EnvelopeIdArg, envelope::arg::ids::EnvelopeIdArg,
@ -45,16 +49,51 @@ pub struct TemplateReplyCommand {
impl TemplateReplyCommand { impl TemplateReplyCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing template reply command"); info!("executing reply template command");
let folder = &self.folder.name; let folder = &self.folder.name;
let id = self.envelope.id; let id = self.envelope.id;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) = let (toml_account_config, account_config) = config.clone().into_account_configs(
config.clone().into_account_configs(account, cache)?; self.account.name.as_ref().map(String::as_str),
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; self.cache.disable,
)?;
let get_messages_kind = toml_account_config.get_messages_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
get_messages_kind,
|builder| match get_messages_kind {
Some(BackendKind::Maildir) => {
builder.set_peek_messages(|ctx| {
ctx.maildir.as_ref().and_then(PeekMessagesMaildir::new)
});
builder
.set_add_flags(|ctx| ctx.maildir.as_ref().and_then(AddFlagsMaildir::new));
}
Some(BackendKind::MaildirForSync) => {
builder.set_peek_messages(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(PeekMessagesMaildir::new)
});
builder.set_add_flags(|ctx| {
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));
}
_ => (),
},
)
.await?;
let tpl: String = backend let tpl: String = backend
.get_messages(folder, &[id]) .get_messages(folder, &[id])

View file

@ -1,13 +1,21 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::message::add_raw::imap::AddRawMessageImap;
#[cfg(feature = "maildir")]
use email::message::add_raw_with_flags::maildir::AddRawMessageWithFlagsMaildir;
use log::info; use log::info;
use mml::MmlCompilerBuilder; use mml::MmlCompilerBuilder;
use std::io::{self, BufRead, IsTerminal}; use std::io::{self, BufRead, IsTerminal};
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, email::template::arg::TemplateRawArg, backend::{Backend, BackendKind},
folder::arg::name::FolderNameOptionalFlag, printer::Printer, cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
email::template::arg::TemplateRawArg,
folder::arg::name::FolderNameOptionalFlag,
printer::Printer,
}; };
/// Save a template to a folder. /// Save a template to a folder.
@ -36,12 +44,43 @@ impl TemplateSaveCommand {
info!("executing template save command"); info!("executing template save command");
let folder = &self.folder.name; let folder = &self.folder.name;
let account = self.account.name.as_ref().map(String::as_str);
let cache = self.cache.disable;
let (toml_account_config, account_config) = let (toml_account_config, account_config) = config.clone().into_account_configs(
config.clone().into_account_configs(account, cache)?; self.account.name.as_ref().map(String::as_str),
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; self.cache.disable,
)?;
let add_message_kind = toml_account_config.add_raw_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)
});
}
_ => (),
},
)
.await?;
let is_tty = io::stdin().is_terminal(); let is_tty = io::stdin().is_terminal();
let is_json = printer.is_json(); let is_json = printer.is_json();

View file

@ -1,12 +1,20 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "sendmail")]
use email::message::send_raw::sendmail::SendRawMessageSendmail;
#[cfg(feature = "smtp")]
use email::message::send_raw::smtp::SendRawMessageSmtp;
use log::info; use log::info;
use mml::MmlCompilerBuilder; use mml::MmlCompilerBuilder;
use std::io::{self, BufRead, IsTerminal}; use std::io::{self, BufRead, IsTerminal};
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, email::template::arg::TemplateRawArg, printer::Printer, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
email::template::arg::TemplateRawArg,
printer::Printer,
}; };
/// Send a template. /// Send a template.
@ -31,12 +39,36 @@ impl TemplateSendCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing template send command"); info!("executing template send command");
let account = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let cache = self.cache.disable; self.account.name.as_ref().map(String::as_str),
self.cache.disable,
)?;
let (toml_account_config, account_config) = let send_message_kind = toml_account_config.send_raw_message_kind();
config.clone().into_account_configs(account, cache)?;
let backend = Backend::new(toml_account_config, account_config.clone(), true).await?; let backend = Backend::new(
&toml_account_config,
&account_config,
send_message_kind,
|builder| {
match send_message_kind {
#[cfg(feature = "smtp")]
Some(BackendKind::Smtp) => {
builder.set_send_raw_message(|ctx| {
ctx.smtp.as_ref().and_then(SendRawMessageSmtp::new)
});
}
#[cfg(feature = "sendmail")]
Some(BackendKind::Sendmail) => {
builder.set_send_raw_message(|ctx| {
ctx.sendmail.as_ref().and_then(SendRawMessageSendmail::new)
});
}
_ => (),
};
},
)
.await?;
let tpl = if io::stdin().is_terminal() { let tpl = if io::stdin().is_terminal() {
self.template.raw() self.template.raw()

View file

@ -30,12 +30,12 @@ pub struct TemplateWriteCommand {
impl TemplateWriteCommand { impl TemplateWriteCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing template write command"); info!("executing write template command");
let account = self.account.name.as_ref().map(String::as_str); let (_, account_config) = config.clone().into_account_configs(
let cache = self.cache.disable; self.account.name.as_ref().map(String::as_str),
self.cache.disable,
let (_, account_config) = config.clone().into_account_configs(account, cache)?; )?;
let tpl: String = Message::new_tpl_builder(&account_config) let tpl: String = Message::new_tpl_builder(&account_config)
.with_headers(self.headers.raw) .with_headers(self.headers.raw)

View file

@ -1,10 +1,18 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::folder::add::imap::AddFolderImap;
#[cfg(feature = "maildir")]
use email::folder::add::maildir::AddFolderMaildir;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
folder::arg::name::FolderNameArg,
printer::Printer,
}; };
/// Create a new folder. /// Create a new folder.
@ -25,19 +33,43 @@ pub struct FolderCreateCommand {
impl FolderCreateCommand { impl FolderCreateCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing folder create command"); info!("executing create folder command");
let folder = &self.folder.name; 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),
self.cache.disable,
)?;
let some_account_name = self.account.name.as_ref().map(String::as_str); let add_folder_kind = toml_account_config.add_folder_kind();
let (toml_account_config, account_config) = config
.clone() let backend = Backend::new(
.into_account_configs(some_account_name, self.cache.disable)?; &toml_account_config,
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; &account_config,
add_folder_kind,
|builder| match add_folder_kind {
Some(BackendKind::Maildir) => {
builder
.set_add_folder(|ctx| ctx.maildir.as_ref().and_then(AddFolderMaildir::new));
}
Some(BackendKind::MaildirForSync) => {
builder.set_add_folder(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(AddFolderMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder.set_add_folder(|ctx| ctx.imap.as_ref().and_then(AddFolderImap::new));
}
_ => (),
},
)
.await?;
backend.add_folder(&folder).await?; backend.add_folder(&folder).await?;
printer.print(format!("Folder {folder} successfully created!"))?;
Ok(()) printer.print(format!("Folder {folder} successfully created!"))
} }
} }

View file

@ -1,12 +1,20 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
use dialoguer::Confirm; use dialoguer::Confirm;
#[cfg(feature = "imap")]
use email::folder::delete::imap::DeleteFolderImap;
#[cfg(feature = "maildir")]
use email::folder::delete::maildir::DeleteFolderMaildir;
use log::info; use log::info;
use std::process; use std::process;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
folder::arg::name::FolderNameArg,
printer::Printer,
}; };
/// Delete a folder. /// Delete a folder.
@ -41,15 +49,42 @@ impl FolderDeleteCommand {
process::exit(0); process::exit(0);
}; };
let some_account_name = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let (toml_account_config, account_config) = config self.account.name.as_ref().map(String::as_str),
.clone() self.cache.disable,
.into_account_configs(some_account_name, self.cache.disable)?; )?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let delete_folder_kind = toml_account_config.delete_folder_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
delete_folder_kind,
|builder| match delete_folder_kind {
Some(BackendKind::Maildir) => {
builder.set_delete_folder(|ctx| {
ctx.maildir.as_ref().and_then(DeleteFolderMaildir::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_delete_folder(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(DeleteFolderMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder
.set_delete_folder(|ctx| ctx.imap.as_ref().and_then(DeleteFolderImap::new));
}
_ => (),
},
)
.await?;
backend.delete_folder(&folder).await?; backend.delete_folder(&folder).await?;
printer.print(format!("Folder {folder} successfully deleted!"))?;
Ok(()) printer.print(format!("Folder {folder} successfully deleted!"))
} }
} }

View file

@ -1,10 +1,18 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::folder::expunge::imap::ExpungeFolderImap;
#[cfg(feature = "maildir")]
use email::folder::expunge::maildir::ExpungeFolderMaildir;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
folder::arg::name::FolderNameArg,
printer::Printer,
}; };
/// Expunge a folder. /// Expunge a folder.
@ -26,19 +34,46 @@ pub struct FolderExpungeCommand {
impl FolderExpungeCommand { impl FolderExpungeCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing folder expunge command"); info!("executing expunge folder command");
let folder = &self.folder.name; 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),
self.cache.disable,
)?;
let some_account_name = self.account.name.as_ref().map(String::as_str); let expunge_folder_kind = toml_account_config.expunge_folder_kind();
let (toml_account_config, account_config) = config
.clone() let backend = Backend::new(
.into_account_configs(some_account_name, self.cache.disable)?; &toml_account_config,
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?; &account_config,
expunge_folder_kind,
|builder| match expunge_folder_kind {
Some(BackendKind::Maildir) => {
builder.set_expunge_folder(|ctx| {
ctx.maildir.as_ref().and_then(ExpungeFolderMaildir::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_expunge_folder(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(ExpungeFolderMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder.set_expunge_folder(|ctx| {
ctx.imap.as_ref().and_then(ExpungeFolderImap::new)
});
}
_ => (),
},
)
.await?;
backend.expunge_folder(&folder).await?; backend.expunge_folder(&folder).await?;
printer.print(format!("Folder {folder} successfully expunged!"))?;
Ok(()) printer.print(format!("Folder {folder} successfully expunged!"))
} }
} }

View file

@ -1,10 +1,14 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
#[cfg(feature = "imap")]
use email::folder::list::imap::ListFoldersImap;
#[cfg(feature = "maildir")]
use email::folder::list::maildir::ListFoldersMaildir;
use log::info; use log::info;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, account::arg::name::AccountNameFlag,
backend::Backend, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag, cache::arg::disable::CacheDisableFlag,
config::TomlConfig, config::TomlConfig,
folder::Folders, folder::Folders,
@ -29,13 +33,41 @@ pub struct FolderListCommand {
impl FolderListCommand { impl FolderListCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing folder list command"); info!("executing list folders command");
let some_account_name = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let (toml_account_config, account_config) = config self.account.name.as_ref().map(String::as_str),
.clone() self.cache.disable,
.into_account_configs(some_account_name, self.cache.disable)?; )?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let list_folders_kind = toml_account_config.list_folders_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
list_folders_kind,
|builder| match list_folders_kind {
Some(BackendKind::Maildir) => {
builder.set_list_folders(|ctx| {
ctx.maildir.as_ref().and_then(ListFoldersMaildir::new)
});
}
Some(BackendKind::MaildirForSync) => {
builder.set_list_folders(|ctx| {
ctx.maildir_for_sync
.as_ref()
.and_then(ListFoldersMaildir::new)
});
}
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder
.set_list_folders(|ctx| ctx.imap.as_ref().and_then(ListFoldersImap::new));
}
_ => (),
},
)
.await?;
let folders: Folders = backend.list_folders().await?.into(); let folders: Folders = backend.list_folders().await?.into();
@ -45,8 +77,6 @@ impl FolderListCommand {
format: &account_config.get_message_read_format(), format: &account_config.get_message_read_format(),
max_width: self.table.max_width, max_width: self.table.max_width,
}, },
)?; )
Ok(())
} }
} }

View file

@ -1,12 +1,18 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
use dialoguer::Confirm; use dialoguer::Confirm;
#[cfg(feature = "imap")]
use email::folder::purge::imap::PurgeFolderImap;
use log::info; use log::info;
use std::process; use std::process;
use crate::{ use crate::{
account::arg::name::AccountNameFlag, backend::Backend, cache::arg::disable::CacheDisableFlag, account::arg::name::AccountNameFlag,
config::TomlConfig, folder::arg::name::FolderNameArg, printer::Printer, backend::{Backend, BackendKind},
cache::arg::disable::CacheDisableFlag,
config::TomlConfig,
folder::arg::name::FolderNameArg,
printer::Printer,
}; };
/// Purge a folder. /// Purge a folder.
@ -27,7 +33,7 @@ pub struct FolderPurgeCommand {
impl FolderPurgeCommand { impl FolderPurgeCommand {
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> { pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
info!("executing folder purge command"); info!("executing purge folder command");
let folder = &self.folder.name; let folder = &self.folder.name;
@ -41,15 +47,43 @@ impl FolderPurgeCommand {
process::exit(0); process::exit(0);
}; };
let some_account_name = self.account.name.as_ref().map(String::as_str); let (toml_account_config, account_config) = config.clone().into_account_configs(
let (toml_account_config, account_config) = config self.account.name.as_ref().map(String::as_str),
.clone() self.cache.disable,
.into_account_configs(some_account_name, self.cache.disable)?; )?;
let backend = Backend::new(toml_account_config, account_config.clone(), false).await?;
let purge_folder_kind = toml_account_config.purge_folder_kind();
let backend = Backend::new(
&toml_account_config,
&account_config,
purge_folder_kind,
|builder| match purge_folder_kind {
// TODO
// Some(BackendKind::Maildir) => {
// builder.set_purge_folder(|ctx| {
// ctx.maildir.as_ref().and_then(PurgeFolderMaildir::new)
// });
// }
// Some(BackendKind::MaildirForSync) => {
// builder.set_purge_folder(|ctx| {
// ctx.maildir_for_sync
// .as_ref()
// .and_then(PurgeFolderMaildir::new)
// });
// }
#[cfg(feature = "imap")]
Some(BackendKind::Imap) => {
builder
.set_purge_folder(|ctx| ctx.imap.as_ref().and_then(PurgeFolderImap::new));
}
_ => (),
},
)
.await?;
backend.purge_folder(&folder).await?; backend.purge_folder(&folder).await?;
printer.print(format!("Folder {folder} successfully purged!"))?;
Ok(()) printer.print(format!("Folder {folder} successfully purged!"))
} }
} }