mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-16 04:17:56 +08:00
re-implement old mailbox commands
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
use clap::Parser;
|
||||
use email::folder::INBOX;
|
||||
|
||||
/// The optional folder name flag parser.
|
||||
const INBOX: &str = "INBOX";
|
||||
|
||||
/// The optional mailbox name flag parser.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct FolderNameOptionalFlag {
|
||||
/// The name of the folder.
|
||||
#[arg(long = "folder", short = 'f')]
|
||||
#[arg(name = "folder_name", value_name = "NAME", default_value = INBOX)]
|
||||
pub struct MailboxNameOptionalFlag {
|
||||
/// The name of the mailbox.
|
||||
#[arg(long = "mailbox", short = 'm')]
|
||||
#[arg(name = "mailbox_name", value_name = "NAME", default_value = INBOX)]
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Default for FolderNameOptionalFlag {
|
||||
impl Default for MailboxNameOptionalFlag {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: INBOX.to_owned(),
|
||||
@@ -18,15 +19,15 @@ impl Default for FolderNameOptionalFlag {
|
||||
}
|
||||
}
|
||||
|
||||
/// The optional folder name argument parser.
|
||||
/// The optional mailbox name argument parser.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct FolderNameOptionalArg {
|
||||
/// The name of the folder.
|
||||
#[arg(name = "folder_name", value_name = "FOLDER", default_value = INBOX)]
|
||||
pub struct MailboxNameOptionalArg {
|
||||
/// The name of the mailbox.
|
||||
#[arg(name = "mailbox_name", value_name = "MAILBOX", default_value = INBOX)]
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Default for FolderNameOptionalArg {
|
||||
impl Default for MailboxNameOptionalArg {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: INBOX.to_owned(),
|
||||
@@ -34,27 +35,27 @@ impl Default for FolderNameOptionalArg {
|
||||
}
|
||||
}
|
||||
|
||||
/// The required folder name argument parser.
|
||||
/// The required mailbox name argument parser.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct FolderNameArg {
|
||||
/// The name of the folder.
|
||||
#[arg(name = "folder_name", value_name = "FOLDER")]
|
||||
pub struct MailboxNameArg {
|
||||
/// The name of the mailbox.
|
||||
#[arg(name = "mailbox_name", value_name = "MAILBOX")]
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
/// The optional source folder name flag parser.
|
||||
/// The optional source mailbox name flag parser.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct SourceFolderNameOptionalFlag {
|
||||
/// The name of the source folder.
|
||||
#[arg(long = "folder", short = 'f')]
|
||||
#[arg(name = "source_folder_name", value_name = "SOURCE", default_value = INBOX)]
|
||||
pub struct SourceMailboxNameOptionalFlag {
|
||||
/// The name of the source mailbox.
|
||||
#[arg(long = "mailbox", short = 'm')]
|
||||
#[arg(name = "source_mailbox_name", value_name = "SOURCE", default_value = INBOX)]
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
/// The target folder name argument parser.
|
||||
/// The target mailbox name argument parser.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct TargetFolderNameArg {
|
||||
/// The name of the target folder.
|
||||
#[arg(name = "target_folder_name", value_name = "TARGET")]
|
||||
pub struct TargetMailboxNameArg {
|
||||
/// The name of the target mailbox.
|
||||
#[arg(name = "target_mailbox_name", value_name = "TARGET")]
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
use email::{
|
||||
config::Config,
|
||||
{backend::feature::BackendFeatureSource, folder::add::AddFolder},
|
||||
};
|
||||
use pimalaya_tui::{
|
||||
himalaya::backend::BackendBuilder,
|
||||
terminal::{cli::printer::Printer, config::TomlConfig as _},
|
||||
};
|
||||
use tracing::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, config::TomlConfig, folder::arg::name::FolderNameArg,
|
||||
};
|
||||
|
||||
/// Create the given folder.
|
||||
///
|
||||
/// This command allows you to create a new folder using the given
|
||||
/// name.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct FolderAddCommand {
|
||||
#[command(flatten)]
|
||||
pub folder: FolderNameArg,
|
||||
|
||||
#[command(flatten)]
|
||||
pub account: AccountNameFlag,
|
||||
}
|
||||
|
||||
impl FolderAddCommand {
|
||||
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_deref(), |c: &Config, name| {
|
||||
c.account(name).ok()
|
||||
})?;
|
||||
|
||||
let backend = BackendBuilder::new(
|
||||
Arc::new(toml_account_config),
|
||||
Arc::new(account_config),
|
||||
|builder| {
|
||||
builder
|
||||
.without_features()
|
||||
.with_add_folder(BackendFeatureSource::Context)
|
||||
},
|
||||
)
|
||||
.without_sending_backend()
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
backend.add_folder(folder).await?;
|
||||
|
||||
printer.out(format!("Folder {folder} successfully created!\n"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
use anyhow::{bail, Result};
|
||||
use clap::Parser;
|
||||
use io_imap::coroutines::create::*;
|
||||
use io_stream::runtimes::std::handle;
|
||||
use pimalaya_toolbox::terminal::printer::{Message, Printer};
|
||||
|
||||
use crate::{config::ImapConfig, imap::mailbox::arg::name::MailboxNameArg, imap::stream};
|
||||
|
||||
/// Create the given mailbox.
|
||||
///
|
||||
/// This command allows you to create a new mailbox using the given
|
||||
/// name.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct CreateMailboxCommand {
|
||||
#[command(flatten)]
|
||||
pub mailbox: MailboxNameArg,
|
||||
}
|
||||
|
||||
impl CreateMailboxCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, config: ImapConfig) -> Result<()> {
|
||||
let (context, mut stream) = stream::connect(config)?;
|
||||
|
||||
let mailbox = self.mailbox.name.try_into()?;
|
||||
|
||||
let mut arg = None;
|
||||
let mut coroutine = ImapCreate::new(context, mailbox);
|
||||
|
||||
loop {
|
||||
match coroutine.resume(arg.take()) {
|
||||
ImapCreateResult::Io(io) => arg = Some(handle(&mut stream, io)?),
|
||||
ImapCreateResult::Ok { .. } => break,
|
||||
ImapCreateResult::Err { err, .. } => bail!(err),
|
||||
}
|
||||
}
|
||||
|
||||
printer.out(Message::new("Mailbox successfully created"))
|
||||
}
|
||||
}
|
||||
@@ -1,73 +1,38 @@
|
||||
use std::{process, sync::Arc};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
use email::{
|
||||
config::Config,
|
||||
{backend::feature::BackendFeatureSource, folder::delete::DeleteFolder},
|
||||
};
|
||||
use pimalaya_tui::{
|
||||
himalaya::backend::BackendBuilder,
|
||||
terminal::{cli::printer::Printer, config::TomlConfig as _, prompt},
|
||||
};
|
||||
use tracing::info;
|
||||
use io_imap::coroutines::delete::*;
|
||||
use io_stream::runtimes::std::handle;
|
||||
use pimalaya_toolbox::terminal::printer::{Message, Printer};
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, config::TomlConfig, folder::arg::name::FolderNameArg,
|
||||
};
|
||||
use crate::{config::ImapConfig, imap::mailbox::arg::name::MailboxNameArg, imap::stream};
|
||||
|
||||
/// Delete the given folder.
|
||||
/// Delete the given mailbox.
|
||||
///
|
||||
/// All emails from the given folder are definitely deleted. The
|
||||
/// folder is also deleted after execution of the command.
|
||||
/// All emails from the given mailbox are definitely deleted. The
|
||||
/// mailbox is also deleted after execution of the command.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct FolderDeleteCommand {
|
||||
pub struct DeleteMailboxCommand {
|
||||
#[command(flatten)]
|
||||
pub folder: FolderNameArg,
|
||||
|
||||
#[command(flatten)]
|
||||
pub account: AccountNameFlag,
|
||||
|
||||
#[arg(long, short)]
|
||||
pub yes: bool,
|
||||
pub mailbox: MailboxNameArg,
|
||||
}
|
||||
|
||||
impl FolderDeleteCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
info!("executing delete folder command");
|
||||
impl DeleteMailboxCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, config: ImapConfig) -> Result<()> {
|
||||
let (context, mut stream) = stream::connect(config)?;
|
||||
|
||||
let folder = &self.folder.name;
|
||||
let mailbox = self.mailbox.name.try_into()?;
|
||||
|
||||
if !self.yes {
|
||||
let confirm = format!("Do you really want to delete the folder {folder}");
|
||||
let confirm = format!("{confirm}? All emails will be definitely deleted.");
|
||||
let mut arg = None;
|
||||
let mut coroutine = ImapDelete::new(context, mailbox);
|
||||
|
||||
if !prompt::bool(confirm, false)? {
|
||||
process::exit(0);
|
||||
};
|
||||
loop {
|
||||
match coroutine.resume(arg.take()) {
|
||||
ImapDeleteResult::Io(io) => arg = Some(handle(&mut stream, io)?),
|
||||
ImapDeleteResult::Ok { .. } => break,
|
||||
ImapDeleteResult::Err { err, .. } => bail!(err),
|
||||
}
|
||||
}
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
.clone()
|
||||
.into_account_configs(self.account.name.as_deref(), |c: &Config, name| {
|
||||
c.account(name).ok()
|
||||
})?;
|
||||
|
||||
let backend = BackendBuilder::new(
|
||||
Arc::new(toml_account_config),
|
||||
Arc::new(account_config),
|
||||
|builder| {
|
||||
builder
|
||||
.without_features()
|
||||
.with_delete_folder(BackendFeatureSource::Context)
|
||||
},
|
||||
)
|
||||
.without_sending_backend()
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
backend.delete_folder(folder).await?;
|
||||
|
||||
printer.out(format!("Folder {folder} successfully deleted!\n"))
|
||||
printer.out(Message::new("Mailbox successfully deleted"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +1,52 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
use email::{
|
||||
backend::feature::BackendFeatureSource, config::Config, folder::expunge::ExpungeFolder,
|
||||
};
|
||||
use pimalaya_tui::{
|
||||
himalaya::backend::BackendBuilder,
|
||||
terminal::{cli::printer::Printer, config::TomlConfig as _},
|
||||
};
|
||||
use tracing::info;
|
||||
use io_imap::coroutines::{expunge::*, select::*};
|
||||
use io_stream::runtimes::std::handle;
|
||||
use pimalaya_toolbox::terminal::printer::{Message, Printer};
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, config::TomlConfig, folder::arg::name::FolderNameArg,
|
||||
};
|
||||
use crate::{config::ImapConfig, imap::mailbox::arg::name::MailboxNameArg, imap::stream};
|
||||
|
||||
/// Expunge the given folder.
|
||||
/// Expunge the given mailbox.
|
||||
///
|
||||
/// The concept of expunging is similar to the IMAP one: it definitely
|
||||
/// deletes emails from the given folder that contain the "deleted"
|
||||
/// deletes emails from the given mailbox that contain the "deleted"
|
||||
/// flag.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct FolderExpungeCommand {
|
||||
pub struct ExpungeMailboxCommand {
|
||||
#[command(flatten)]
|
||||
pub folder: FolderNameArg,
|
||||
|
||||
#[command(flatten)]
|
||||
pub account: AccountNameFlag,
|
||||
pub mailbox: MailboxNameArg,
|
||||
}
|
||||
|
||||
impl FolderExpungeCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
info!("executing expunge folder command");
|
||||
impl ExpungeMailboxCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, config: ImapConfig) -> Result<()> {
|
||||
let (context, mut stream) = stream::connect(config)?;
|
||||
|
||||
let folder = &self.folder.name;
|
||||
let (toml_account_config, account_config) = config
|
||||
.clone()
|
||||
.into_account_configs(self.account.name.as_deref(), |c: &Config, name| {
|
||||
c.account(name).ok()
|
||||
})?;
|
||||
let mailbox = self.mailbox.name.try_into()?;
|
||||
|
||||
let backend = BackendBuilder::new(
|
||||
Arc::new(toml_account_config),
|
||||
Arc::new(account_config),
|
||||
|builder| {
|
||||
builder
|
||||
.without_features()
|
||||
.with_expunge_folder(BackendFeatureSource::Context)
|
||||
},
|
||||
)
|
||||
.without_sending_backend()
|
||||
.build()
|
||||
.await?;
|
||||
// First, select the mailbox
|
||||
let mut arg = None;
|
||||
let mut coroutine = ImapSelect::new(context, mailbox);
|
||||
|
||||
backend.expunge_folder(folder).await?;
|
||||
let context = loop {
|
||||
match coroutine.resume(arg.take()) {
|
||||
ImapSelectResult::Io(io) => arg = Some(handle(&mut stream, io)?),
|
||||
ImapSelectResult::Ok { context, .. } => break context,
|
||||
ImapSelectResult::Err { err, .. } => bail!(err),
|
||||
}
|
||||
};
|
||||
|
||||
printer.out(format!("Folder {folder} successfully expunged!\n"))
|
||||
// Then, expunge it
|
||||
let mut arg = None;
|
||||
let mut coroutine = ImapExpunge::new(context);
|
||||
|
||||
loop {
|
||||
match coroutine.resume(arg.take()) {
|
||||
ImapExpungeResult::Io(io) => arg = Some(handle(&mut stream, io)?),
|
||||
ImapExpungeResult::Ok { .. } => break,
|
||||
ImapExpungeResult::Err { err, .. } => bail!(err),
|
||||
}
|
||||
}
|
||||
|
||||
printer.out(Message::new("Mailbox successfully expunged"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
// mod add;
|
||||
// mod delete;
|
||||
// mod expunge;
|
||||
pub mod create;
|
||||
pub mod delete;
|
||||
pub mod expunge;
|
||||
pub mod list;
|
||||
// mod purge;
|
||||
pub mod purge;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use pimalaya_toolbox::terminal::printer::Printer;
|
||||
|
||||
use crate::{config::ImapConfig, imap::mailbox::command::list::ListMailboxesCommand};
|
||||
use crate::{
|
||||
config::ImapConfig,
|
||||
imap::mailbox::command::{
|
||||
create::CreateMailboxCommand, delete::DeleteMailboxCommand,
|
||||
expunge::ExpungeMailboxCommand, list::ListMailboxesCommand, purge::PurgeMailboxCommand,
|
||||
},
|
||||
};
|
||||
|
||||
/// Create, list and purge mailboxes.
|
||||
///
|
||||
@@ -16,28 +22,23 @@ use crate::{config::ImapConfig, imap::mailbox::command::list::ListMailboxesComma
|
||||
/// manage them.
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum MailboxCommand {
|
||||
// #[command(visible_alias = "create", alias = "new")]
|
||||
// Add(FolderAddCommand),
|
||||
#[command(alias = "add", alias = "new")]
|
||||
Create(CreateMailboxCommand),
|
||||
#[command(alias = "remove", alias = "rm")]
|
||||
Delete(DeleteMailboxCommand),
|
||||
Expunge(ExpungeMailboxCommand),
|
||||
List(ListMailboxesCommand),
|
||||
// #[command()]
|
||||
// Expunge(FolderExpungeCommand),
|
||||
|
||||
// #[command()]
|
||||
// Purge(FolderPurgeCommand),
|
||||
|
||||
// #[command(alias = "remove", alias = "rm")]
|
||||
// Delete(FolderDeleteCommand),
|
||||
Purge(PurgeMailboxCommand),
|
||||
}
|
||||
|
||||
impl MailboxCommand {
|
||||
#[allow(unused)]
|
||||
pub fn execute(self, printer: &mut impl Printer, config: ImapConfig) -> Result<()> {
|
||||
match self {
|
||||
// Self::Add(cmd) => cmd.execute(printer, config).await,
|
||||
Self::Create(cmd) => cmd.execute(printer, config),
|
||||
Self::Delete(cmd) => cmd.execute(printer, config),
|
||||
Self::Expunge(cmd) => cmd.execute(printer, config),
|
||||
Self::List(cmd) => cmd.execute(printer, config),
|
||||
// Self::Expunge(cmd) => cmd.execute(printer, config).await,
|
||||
// Self::Purge(cmd) => cmd.execute(printer, config).await,
|
||||
// Self::Delete(cmd) => cmd.execute(printer, config).await,
|
||||
Self::Purge(cmd) => cmd.execute(printer, config),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,76 @@
|
||||
use std::{process, sync::Arc};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
use email::{backend::feature::BackendFeatureSource, config::Config, folder::purge::PurgeFolder};
|
||||
use pimalaya_tui::{
|
||||
himalaya::backend::BackendBuilder,
|
||||
terminal::{cli::printer::Printer, config::TomlConfig as _, prompt},
|
||||
use io_imap::{
|
||||
coroutines::{expunge::*, select::*, store::*},
|
||||
types::{
|
||||
flag::{Flag, StoreType},
|
||||
sequence::SequenceSet,
|
||||
},
|
||||
};
|
||||
use tracing::info;
|
||||
use io_stream::runtimes::std::handle;
|
||||
use pimalaya_toolbox::terminal::printer::{Message, Printer};
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag, config::TomlConfig, folder::arg::name::FolderNameArg,
|
||||
};
|
||||
use crate::{config::ImapConfig, imap::mailbox::arg::name::MailboxNameArg, imap::stream};
|
||||
|
||||
/// Purge the given folder.
|
||||
/// Purge the given mailbox.
|
||||
///
|
||||
/// All emails from the given folder are definitely deleted. The
|
||||
/// purged folder will remain empty after execution of the command.
|
||||
/// All emails from the given mailbox are definitely deleted. The
|
||||
/// purged mailbox will remain empty after execution of the command.
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct FolderPurgeCommand {
|
||||
pub struct PurgeMailboxCommand {
|
||||
#[command(flatten)]
|
||||
pub folder: FolderNameArg,
|
||||
|
||||
#[command(flatten)]
|
||||
pub account: AccountNameFlag,
|
||||
|
||||
#[arg(long, short)]
|
||||
pub yes: bool,
|
||||
pub mailbox: MailboxNameArg,
|
||||
}
|
||||
|
||||
impl FolderPurgeCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
info!("executing purge folder command");
|
||||
impl PurgeMailboxCommand {
|
||||
pub fn execute(self, printer: &mut impl Printer, config: ImapConfig) -> Result<()> {
|
||||
let (context, mut stream) = stream::connect(config)?;
|
||||
|
||||
let folder = &self.folder.name;
|
||||
let mailbox = self.mailbox.name.try_into()?;
|
||||
|
||||
if !self.yes {
|
||||
let confirm = format!("Do you really want to purge the folder {folder}");
|
||||
let confirm = format!("{confirm}? All emails will be definitely deleted.");
|
||||
// First, select the mailbox
|
||||
let mut arg = None;
|
||||
let mut coroutine = ImapSelect::new(context, mailbox);
|
||||
|
||||
if !prompt::bool(confirm, false)? {
|
||||
process::exit(0);
|
||||
};
|
||||
let context = loop {
|
||||
match coroutine.resume(arg.take()) {
|
||||
ImapSelectResult::Io(io) => arg = Some(handle(&mut stream, io)?),
|
||||
ImapSelectResult::Ok { context, .. } => break context,
|
||||
ImapSelectResult::Err { err, .. } => bail!(err),
|
||||
}
|
||||
};
|
||||
|
||||
let (toml_account_config, account_config) = config
|
||||
.clone()
|
||||
.into_account_configs(self.account.name.as_deref(), |c: &Config, name| {
|
||||
c.account(name).ok()
|
||||
})?;
|
||||
// Then, mark all messages as deleted (1:*)
|
||||
let mut arg = None;
|
||||
let sequence_set: SequenceSet = "1:*".try_into()?;
|
||||
let mut coroutine = ImapStoreSilent::new(
|
||||
context,
|
||||
sequence_set,
|
||||
StoreType::Add,
|
||||
vec![Flag::Deleted],
|
||||
false,
|
||||
);
|
||||
|
||||
let backend = BackendBuilder::new(
|
||||
Arc::new(toml_account_config),
|
||||
Arc::new(account_config),
|
||||
|builder| {
|
||||
builder
|
||||
.without_features()
|
||||
.with_purge_folder(BackendFeatureSource::Context)
|
||||
},
|
||||
)
|
||||
.without_sending_backend()
|
||||
.build()
|
||||
.await?;
|
||||
let context = loop {
|
||||
match coroutine.resume(arg.take()) {
|
||||
ImapStoreSilentResult::Io(io) => arg = Some(handle(&mut stream, io)?),
|
||||
ImapStoreSilentResult::Ok { context, .. } => break context,
|
||||
ImapStoreSilentResult::Err { err, .. } => bail!(err),
|
||||
}
|
||||
};
|
||||
|
||||
backend.purge_folder(folder).await?;
|
||||
// Finally, expunge the mailbox
|
||||
let mut arg = None;
|
||||
let mut coroutine = ImapExpunge::new(context);
|
||||
|
||||
printer.out(format!("Folder {folder} successfully purged!\n"))
|
||||
loop {
|
||||
match coroutine.resume(arg.take()) {
|
||||
ImapExpungeResult::Io(io) => arg = Some(handle(&mut stream, io)?),
|
||||
ImapExpungeResult::Ok { .. } => break,
|
||||
ImapExpungeResult::Err { err, .. } => bail!(err),
|
||||
}
|
||||
}
|
||||
|
||||
printer.out(Message::new("Mailbox successfully purged"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// pub mod arg;
|
||||
pub mod arg;
|
||||
pub mod command;
|
||||
|
||||
Reference in New Issue
Block a user