Skip to content

Commit 4d74db8

Browse files
committed
feat: implement delete subcommand
1 parent b974057 commit 4d74db8

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

src/arguments/delete.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use std::io::{self};
2+
3+
use clap::Args;
4+
use color_eyre::eyre::eyre;
5+
6+
use crate::otp::otp_element::OTPDatabase;
7+
8+
use super::SubcommandExecutor;
9+
10+
#[derive(Args)]
11+
pub struct DeleteArgs {
12+
/// Code Index
13+
#[arg(short, long, required_unless_present_any=["issuer", "label"])]
14+
pub index: Option<usize>,
15+
16+
/// Issuer of the first matching code that will be deleted
17+
#[arg(short = 's', long, required_unless_present_any=["index", "label"])]
18+
pub issuer: Option<String>,
19+
20+
/// Label of the first matching code that will be deleted
21+
#[arg(short, long, required_unless_present_any=["index","issuer"])]
22+
pub label: Option<String>,
23+
}
24+
25+
impl SubcommandExecutor for DeleteArgs {
26+
fn run_command(self, mut otp_database: OTPDatabase) -> color_eyre::Result<OTPDatabase> {
27+
let index_to_delete = self
28+
.index
29+
.and_then(|i| i.checked_sub(1))
30+
.or_else(|| get_first_matching_element(&otp_database, &self))
31+
.ok_or(eyre!("No code has been found using the given arguments"))?;
32+
33+
let mut output = String::with_capacity(1);
34+
35+
let element = otp_database.elements_ref().get(index_to_delete).unwrap();
36+
println!(
37+
"Are you sure you want to delete the {}th code ({}, {}) [Y,N]: ",
38+
index_to_delete, element.issuer, element.label
39+
);
40+
41+
io::stdin().read_line(&mut output)?;
42+
43+
if output.eq_ignore_ascii_case("y") {
44+
otp_database.delete_element(index_to_delete);
45+
Ok(otp_database)
46+
} else {
47+
Err(eyre!("Operation interrupt by the user"))
48+
}
49+
}
50+
}
51+
52+
fn get_first_matching_element(
53+
otp_database: &OTPDatabase,
54+
delete_args: &DeleteArgs,
55+
) -> Option<usize> {
56+
otp_database
57+
.elements_ref()
58+
.iter()
59+
.enumerate()
60+
.find(|(_, element)| {
61+
element.issuer.contains(
62+
delete_args
63+
.issuer
64+
.as_ref()
65+
.map(|s| s.as_str())
66+
.unwrap_or(""),
67+
) && element
68+
.label
69+
.contains(delete_args.label.as_ref().map(|s| s.as_str()).unwrap_or(""))
70+
})
71+
.map(|(index, _)| index)
72+
}

src/arguments/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use self::{
1010
};
1111

1212
mod add;
13+
mod delete;
1314
mod edit;
1415
mod export;
1516
mod extract;

0 commit comments

Comments
 (0)