diff --git a/src/cli/add_command.rs b/src/cli/add_command.rs index 2c3a9b3..709cd1a 100644 --- a/src/cli/add_command.rs +++ b/src/cli/add_command.rs @@ -50,6 +50,7 @@ pub struct Add { impl LprsCommand for Add { fn run(mut self, mut vault_manager: Vaults) -> LprsResult<()> { if !self.vault_info.is_empty() { + self.vault_info.name = self.vault_info.name.trim().to_string(); self.vault_info.password = utils::user_password(self.password, "Vault password:")?; self.vault_info.custom_fields = self.custom_fields.into_iter().collect(); vault_manager.add_vault(self.vault_info); diff --git a/src/cli/edit_command.rs b/src/cli/edit_command.rs index 98ec47b..6586e60 100644 --- a/src/cli/edit_command.rs +++ b/src/cli/edit_command.rs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use std::num::NonZeroU64; - use clap::Args; use crate::{clap_parsers, utils, vault::Vaults, LprsCommand, LprsError, LprsResult}; @@ -24,8 +22,9 @@ use crate::{clap_parsers, utils, vault::Vaults, LprsCommand, LprsError, LprsResu #[command(author, version, about, long_about = None)] /// Edit command, used to edit the vault content pub struct Edit { - /// The password index. You can get it from the list command - index: NonZeroU64, + /// The vault to edit, index or name + #[arg(name = "INDEX-or-NAME")] + location: String, #[arg(short, long)] /// The new vault name @@ -58,16 +57,16 @@ pub struct Edit { impl LprsCommand for Edit { fn run(self, mut vault_manager: Vaults) -> LprsResult<()> { - let index = self.index.get() as usize; - log::debug!("Editing vault at index: {index}"); - - let Some(vault) = vault_manager.vaults.get_mut(index - 1) else { - return Err(LprsError::InvalidVaultIndex(format!( - "The index `{}` is greater than the vaults count {}", - self.index, - vault_manager.vaults.len() - ))); - }; + let vault = + match utils::vault_by_index_or_name(self.location.trim(), &mut vault_manager.vaults) { + Ok((_, v)) => v, + Err(err) => { + if self.force { + return Ok(()); + } + return Err(err); + } + }; log::info!("Applying the new values to the vault"); if let Some(new_name) = self.name { diff --git a/src/cli/get_command.rs b/src/cli/get_command.rs index 5c79568..73f72eb 100644 --- a/src/cli/get_command.rs +++ b/src/cli/get_command.rs @@ -19,6 +19,7 @@ use std::str::FromStr; use clap::Args; use crate::{ + utils, vault::{Vault, Vaults}, LprsCommand, LprsError, @@ -96,27 +97,9 @@ pub struct Get { } impl LprsCommand for Get { - fn run(self, vault_manager: Vaults) -> LprsResult<()> { - let parsed_index = self.location.trim().parse::(); - let Some((index, vault)) = (if let Ok(index) = parsed_index { - vault_manager.vaults.get(index - 1).map(|v| (index, v)) - } else { - vault_manager - .vaults - .iter() - .enumerate() - .find(|(_, v)| v.name == self.location) - }) else { - return Err(LprsError::Other(format!( - "There is no vault with the given {} `{}`", - if parsed_index.is_ok() { - "index" - } else { - "name" - }, - self.location.trim(), - ))); - }; + fn run(self, mut vault_manager: Vaults) -> LprsResult<()> { + let (index, vault) = + utils::vault_by_index_or_name(self.location.trim(), &mut vault_manager.vaults)?; if let Some(field) = self.field { if field == VaultGetField::Index { diff --git a/src/cli/remove_command.rs b/src/cli/remove_command.rs index 8215c29..934573b 100644 --- a/src/cli/remove_command.rs +++ b/src/cli/remove_command.rs @@ -14,44 +14,37 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use std::num::NonZeroU64; - use clap::Args; -use crate::{vault::Vaults, LprsCommand, LprsError, LprsResult}; +use crate::{utils, vault::Vaults, LprsCommand, LprsResult}; #[derive(Debug, Args)] #[command(author, version, about, long_about = None)] /// Remove command, used to remove a vault from the vaults file pub struct Remove { - /// The password index - index: NonZeroU64, + /// The vault to remove, index or name + #[arg(name = "INDEX-or-NAME")] + location: String, - /// Force remove, will not return error if there is no password with this - /// index + /// Force remove, will not return error if there is no vault with the given + /// index or name #[arg(short, long)] force: bool, } impl LprsCommand for Remove { fn run(self, mut vault_manager: Vaults) -> LprsResult<()> { - let index = (self.index.get() - 1) as usize; - log::debug!("Removing vault at index: {index}"); - - if index > vault_manager.vaults.len() { - if self.force { - log::error!( - "The index is greater than the passwords counts, but the force flag is enabled" - ); - } else { - return Err(LprsError::Other( - "The index is greater than the passwords counts".to_owned(), - )); - } - } else { - vault_manager.vaults.remove(index); - vault_manager.try_export()?; - } - Ok(()) + let index = + match utils::vault_by_index_or_name(self.location.trim(), &mut vault_manager.vaults) { + Ok((idx, _)) => idx, + Err(err) => { + if self.force { + return Ok(()); + } + return Err(err); + } + }; + vault_manager.vaults.remove(index); + vault_manager.try_export() } } diff --git a/src/utils.rs b/src/utils.rs index 04c2ff3..71b999d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -23,6 +23,7 @@ use passwords::{analyzer, scorer}; use reqwest::blocking::Client as BlockingClient; use sha2::Digest; +use crate::vault::Vault; use crate::{LprsError, LprsResult}; /// Returns the local project dir joined with the given file name @@ -205,3 +206,34 @@ pub fn apply_custom_fields( } } } + +/// Returns the vault with its index by its index or name +/// +/// ## Errors +/// - If there is no vault with the given index or name +pub fn vault_by_index_or_name<'a>( + index_or_name: &str, + vaults: &'a mut [Vault], +) -> LprsResult<(usize, &'a mut Vault)> { + let parsed_index = index_or_name.parse::(); + + let Some((index, vault)) = (if let Ok(index) = parsed_index { + vaults.get_mut(index - 1).map(|v| (index, v)) + } else { + vaults + .iter_mut() + .enumerate() + .find(|(_, v)| v.name == index_or_name) + }) else { + return Err(LprsError::Other(format!( + "There is no vault with the given {} `{}`", + if parsed_index.is_ok() { + "index" + } else { + "name" + }, + index_or_name, + ))); + }; + Ok((index, vault)) +}