mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-17 05:07:55 +08:00
refactor envelope with clap derive api
This commit is contained in:
@@ -1,91 +0,0 @@
|
||||
//! Email CLI module.
|
||||
//!
|
||||
//! This module contains the command matcher, the subcommands and the
|
||||
//! arguments related to the email domain.
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::{Arg, ArgMatches, Command};
|
||||
|
||||
use crate::ui::table;
|
||||
|
||||
const ARG_PAGE: &str = "page";
|
||||
const ARG_PAGE_SIZE: &str = "page-size";
|
||||
const CMD_LIST: &str = "list";
|
||||
const CMD_ENVELOPE: &str = "envelope";
|
||||
|
||||
pub type Page = usize;
|
||||
pub type PageSize = usize;
|
||||
|
||||
/// Represents the email commands.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Cmd {
|
||||
List(table::args::MaxTableWidth, Option<PageSize>, Page),
|
||||
}
|
||||
|
||||
/// Email command matcher.
|
||||
pub fn matches(m: &ArgMatches) -> Result<Option<Cmd>> {
|
||||
let cmd = if let Some(m) = m.subcommand_matches(CMD_ENVELOPE) {
|
||||
if let Some(m) = m.subcommand_matches(CMD_LIST) {
|
||||
let max_table_width = table::args::parse_max_width(m);
|
||||
let page_size = parse_page_size_arg(m);
|
||||
let page = parse_page_arg(m);
|
||||
Some(Cmd::List(max_table_width, page_size, page))
|
||||
} else {
|
||||
Some(Cmd::List(None, None, 0))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(cmd)
|
||||
}
|
||||
|
||||
/// Represents the envelope subcommand.
|
||||
pub fn subcmd() -> Command {
|
||||
Command::new(CMD_ENVELOPE)
|
||||
.about("Subcommand to manage envelopes")
|
||||
.long_about("Subcommand to manage envelopes like list")
|
||||
.subcommands([Command::new(CMD_LIST)
|
||||
.alias("lst")
|
||||
.about("List envelopes")
|
||||
.arg(page_size_arg())
|
||||
.arg(page_arg())
|
||||
.arg(table::args::max_width())])
|
||||
}
|
||||
|
||||
/// Represents the page size argument.
|
||||
fn page_size_arg() -> Arg {
|
||||
Arg::new(ARG_PAGE_SIZE)
|
||||
.help("Page size")
|
||||
.long("page-size")
|
||||
.short('s')
|
||||
.value_name("INT")
|
||||
}
|
||||
|
||||
/// Represents the page size argument parser.
|
||||
fn parse_page_size_arg(matches: &ArgMatches) -> Option<usize> {
|
||||
matches
|
||||
.get_one::<String>(ARG_PAGE_SIZE)
|
||||
.and_then(|s| s.parse().ok())
|
||||
}
|
||||
|
||||
/// Represents the page argument.
|
||||
fn page_arg() -> Arg {
|
||||
Arg::new(ARG_PAGE)
|
||||
.help("Page number")
|
||||
.short('p')
|
||||
.long("page")
|
||||
.value_name("INT")
|
||||
.default_value("1")
|
||||
}
|
||||
|
||||
/// Represents the page argument parser.
|
||||
fn parse_page_arg(matches: &ArgMatches) -> usize {
|
||||
matches
|
||||
.get_one::<String>(ARG_PAGE)
|
||||
.unwrap()
|
||||
.parse()
|
||||
.ok()
|
||||
.map(|page| 1.max(page) - 1)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use log::info;
|
||||
|
||||
use crate::{
|
||||
account::arg::name::AccountNameFlag,
|
||||
backend::Backend,
|
||||
cache::arg::disable::DisableCacheFlag,
|
||||
config::TomlConfig,
|
||||
folder::arg::name::FolderNameOptionalArg,
|
||||
printer::{PrintTableOpts, Printer},
|
||||
ui::arg::max_width::MaxTableWidthFlag,
|
||||
};
|
||||
|
||||
/// List all envelopes from a folder
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct EnvelopeListCommand {
|
||||
#[command(flatten)]
|
||||
pub folder: FolderNameOptionalArg,
|
||||
|
||||
/// The page number
|
||||
#[arg(long, short, value_name = "NUMBER", default_value = "1")]
|
||||
pub page: usize,
|
||||
|
||||
/// The page size
|
||||
#[arg(long, short = 's', value_name = "NUMBER")]
|
||||
pub page_size: Option<usize>,
|
||||
|
||||
#[command(flatten)]
|
||||
pub table: MaxTableWidthFlag,
|
||||
|
||||
#[command(flatten)]
|
||||
pub account: AccountNameFlag,
|
||||
|
||||
#[command(flatten)]
|
||||
pub cache: DisableCacheFlag,
|
||||
}
|
||||
|
||||
impl EnvelopeListCommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
info!("executing envelope list command");
|
||||
|
||||
let folder = &self.folder.name;
|
||||
|
||||
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 = Backend::new(toml_account_config, account_config.clone(), false).await?;
|
||||
|
||||
let page_size = self
|
||||
.page_size
|
||||
.unwrap_or(account_config.email_listing_page_size());
|
||||
let page = 1.max(self.page) - 1;
|
||||
|
||||
let envelopes = backend.list_envelopes(folder, page_size, page).await?;
|
||||
|
||||
printer.print_table(
|
||||
Box::new(envelopes),
|
||||
PrintTableOpts {
|
||||
format: &account_config.email_reading_format,
|
||||
max_width: self.table.max_width,
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
pub mod list;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
|
||||
use crate::{config::TomlConfig, printer::Printer};
|
||||
|
||||
use self::list::EnvelopeListCommand;
|
||||
|
||||
/// Subcommand to manage envelopes
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum EnvelopeSubcommand {
|
||||
/// List all envelopes from a folder
|
||||
#[command(alias = "lst")]
|
||||
List(EnvelopeListCommand),
|
||||
}
|
||||
|
||||
impl EnvelopeSubcommand {
|
||||
pub async fn execute(self, printer: &mut impl Printer, config: &TomlConfig) -> Result<()> {
|
||||
match self {
|
||||
Self::List(cmd) => cmd.execute(printer, config).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use email::account::config::AccountConfig;
|
||||
use log::{debug, trace};
|
||||
|
||||
use crate::{
|
||||
backend::Backend,
|
||||
printer::{PrintTableOpts, Printer},
|
||||
};
|
||||
|
||||
pub async fn list<P: Printer>(
|
||||
config: &AccountConfig,
|
||||
printer: &mut P,
|
||||
backend: &Backend,
|
||||
folder: &str,
|
||||
max_width: Option<usize>,
|
||||
page_size: Option<usize>,
|
||||
page: usize,
|
||||
) -> Result<()> {
|
||||
let page_size = page_size.unwrap_or(config.email_listing_page_size());
|
||||
debug!("page size: {}", page_size);
|
||||
|
||||
let envelopes = backend.list_envelopes(&folder, page_size, page).await?;
|
||||
trace!("envelopes: {:?}", envelopes);
|
||||
|
||||
printer.print_table(
|
||||
Box::new(envelopes),
|
||||
PrintTableOpts {
|
||||
format: &config.email_reading_format,
|
||||
max_width,
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
pub mod args;
|
||||
pub mod command;
|
||||
pub mod config;
|
||||
pub mod flag;
|
||||
pub mod handlers;
|
||||
|
||||
use anyhow::Result;
|
||||
use email::account::config::AccountConfig;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
use anyhow::Result;
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
|
||||
use crate::{folder, template};
|
||||
use crate::template;
|
||||
|
||||
const ARG_CRITERIA: &str = "criterion";
|
||||
const ARG_HEADERS: &str = "headers";
|
||||
@@ -71,7 +71,7 @@ pub fn matches(m: &ArgMatches) -> Result<Option<Cmd>> {
|
||||
Some(Cmd::Attachments(ids))
|
||||
} else if let Some(m) = m.subcommand_matches(CMD_COPY) {
|
||||
let ids = parse_ids_arg(m);
|
||||
let folder = folder::args::parse_target_arg(m);
|
||||
let folder = "INBOX";
|
||||
Some(Cmd::Copy(ids, folder))
|
||||
} else if let Some(m) = m.subcommand_matches(CMD_DELETE) {
|
||||
let ids = parse_ids_arg(m);
|
||||
@@ -83,7 +83,7 @@ pub fn matches(m: &ArgMatches) -> Result<Option<Cmd>> {
|
||||
Some(Cmd::Forward(id, headers, body))
|
||||
} else if let Some(m) = m.subcommand_matches(CMD_MOVE) {
|
||||
let ids = parse_ids_arg(m);
|
||||
let folder = folder::args::parse_target_arg(m);
|
||||
let folder = "INBOX";
|
||||
Some(Cmd::Move(ids, folder))
|
||||
} else if let Some(m) = m.subcommand_matches(CMD_READ) {
|
||||
let ids = parse_ids_arg(m);
|
||||
@@ -158,12 +158,12 @@ pub fn subcmd() -> Command {
|
||||
Command::new(CMD_COPY)
|
||||
.alias("cp")
|
||||
.about("Copy emails to the given folder")
|
||||
.arg(folder::args::target_arg())
|
||||
// .arg(folder::args::target_arg())
|
||||
.arg(ids_arg()),
|
||||
Command::new(CMD_MOVE)
|
||||
.alias("mv")
|
||||
.about("Move emails to the given folder")
|
||||
.arg(folder::args::target_arg())
|
||||
// .arg(folder::args::target_arg())
|
||||
.arg(ids_arg()),
|
||||
Command::new(CMD_DELETE)
|
||||
.aliases(["remove", "rm"])
|
||||
|
||||
Reference in New Issue
Block a user