add create and delete folder commands #54

This commit is contained in:
Clément DOUIN 2023-02-20 18:26:10 +01:00
parent 5734b30fd1
commit 21d8d57f72
No known key found for this signature in database
GPG key ID: 353E4A18EE0FAB72
4 changed files with 78 additions and 7 deletions

View file

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Added `create` and `delete` folder commands [sourcehut#54].
### Fixed
- Fixed config deserialization issue with `email-hooks` and
@ -670,3 +674,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#356]: https://github.com/soywod/himalaya/issues/356
[#419]: https://github.com/soywod/himalaya/issues/419
[#430]: https://github.com/soywod/himalaya/issues/430
[sourcehut#54]: https://todo.sr.ht/~soywod/pimalaya/54

View file

@ -11,6 +11,8 @@ use crate::ui::table;
const ARG_SOURCE: &str = "source";
const ARG_TARGET: &str = "target";
const CMD_CREATE: &str = "create";
const CMD_DELETE: &str = "delete";
const CMD_EXPUNGE: &str = "expunge";
const CMD_FOLDERS: &str = "folders";
const CMD_LIST: &str = "list";
@ -18,8 +20,10 @@ const CMD_LIST: &str = "list";
/// Represents the folder commands.
#[derive(Debug, PartialEq, Eq)]
pub enum Cmd {
Create,
List(table::args::MaxTableWidth),
Expunge,
Delete,
}
/// Represents the folder command matcher.
@ -28,10 +32,16 @@ pub fn matches(m: &ArgMatches) -> Result<Option<Cmd>> {
if let Some(_) = m.subcommand_matches(CMD_EXPUNGE) {
info!("expunge folder subcommand matched");
Some(Cmd::Expunge)
} else if let Some(_) = m.subcommand_matches(CMD_CREATE) {
debug!("create folder command matched");
Some(Cmd::Create)
} else if let Some(m) = m.subcommand_matches(CMD_LIST) {
debug!("list folders command matched");
let max_table_width = table::args::parse_max_width(m);
Some(Cmd::List(max_table_width))
} else if let Some(_) = m.subcommand_matches(CMD_DELETE) {
debug!("delete folder command matched");
Some(Cmd::Delete)
} else {
info!("no folder subcommand matched, falling back to subcommand list");
Some(Cmd::List(None))
@ -49,9 +59,15 @@ pub fn subcmd() -> Command {
.about("Manage folders")
.subcommands([
Command::new(CMD_EXPUNGE).about("Delete emails marked for deletion"),
Command::new(CMD_CREATE)
.aliases(["add", "new"])
.about("Create a new folder"),
Command::new(CMD_LIST)
.about("List folders")
.arg(table::args::max_width()),
Command::new(CMD_DELETE)
.aliases(["remove", "rm"])
.about("Delete a folder with all its emails"),
])
}

View file

@ -3,7 +3,9 @@
//! This module gathers all folder actions triggered by the CLI.
use anyhow::Result;
use dialoguer::Confirm;
use himalaya_lib::{AccountConfig, Backend};
use std::process;
use crate::{
printer::{PrintTableOpts, Printer},
@ -11,19 +13,19 @@ use crate::{
};
pub fn expunge<P: Printer, B: Backend + ?Sized>(
folder: &str,
printer: &mut P,
backend: &mut B,
folder: &str,
) -> Result<()> {
backend.expunge_folder(folder)?;
printer.print(format!("Folder {folder} successfully expunged!"))
}
pub fn list<P: Printer, B: Backend + ?Sized>(
max_width: Option<usize>,
config: &AccountConfig,
printer: &mut P,
backend: &mut B,
max_width: Option<usize>,
) -> Result<()> {
let folders: Folders = backend.list_folders()?.into();
printer.print_table(
@ -36,6 +38,33 @@ pub fn list<P: Printer, B: Backend + ?Sized>(
)
}
pub fn create<P: Printer, B: Backend + ?Sized>(
printer: &mut P,
backend: &mut B,
folder: &str,
) -> Result<()> {
backend.add_folder(folder)?;
printer.print("Folder successfully created!")
}
pub fn delete<P: Printer, B: Backend + ?Sized>(
printer: &mut P,
backend: &mut B,
folder: &str,
) -> Result<()> {
if let Some(false) | None = Confirm::new()
.with_prompt(format!("Confirm deletion of folder {folder}?"))
.default(false)
.report(false)
.interact_opt()?
{
process::exit(0);
};
backend.delete_folder(folder)?;
printer.print("Folder successfully deleted!")
}
#[cfg(test)]
mod tests {
use himalaya_lib::{

View file

@ -1,4 +1,4 @@
use anyhow::Result;
use anyhow::{anyhow, Context, Result};
use clap::Command;
use std::{borrow::Cow, env};
use url::Url;
@ -147,24 +147,44 @@ fn main() -> Result<()> {
// checks folder commands
match folder::args::matches(&m)? {
Some(folder::args::Cmd::Expunge) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
Some(folder::args::Cmd::Create) => {
let folder = folder
.ok_or_else(|| anyhow!("the folder argument is missing"))
.context("cannot create folder")?;
let folder = account_config.folder_alias(folder)?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return folder::handlers::expunge(&folder, &mut printer, backend.as_mut());
return folder::handlers::create(&mut printer, backend.as_mut(), &folder);
}
Some(folder::args::Cmd::List(max_width)) => {
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return folder::handlers::list(
max_width,
&account_config,
&mut printer,
backend.as_mut(),
max_width,
);
}
Some(folder::args::Cmd::Expunge) => {
let folder = account_config.folder_alias(folder.unwrap_or(DEFAULT_INBOX_FOLDER))?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return folder::handlers::expunge(&mut printer, backend.as_mut(), &folder);
}
Some(folder::args::Cmd::Delete) => {
let folder = folder
.ok_or_else(|| anyhow!("the folder argument is missing"))
.context("cannot delete folder")?;
let folder = account_config.folder_alias(folder)?;
let mut backend = BackendBuilder::new()
.disable_cache(disable_cache)
.build(&account_config, &backend_config)?;
return folder::handlers::delete(&mut printer, backend.as_mut(), &folder);
}
_ => (),
}