diff --git a/src/cli/edit_command.rs b/src/cli/edit_command.rs new file mode 100644 index 0000000..83de8af --- /dev/null +++ b/src/cli/edit_command.rs @@ -0,0 +1,89 @@ +// Local CLI password manager +// Copyright (C) 2024 Awiteb +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// 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::{ + password::{Password, Passwords}, + PassrsError, PassrsResult, RunCommand, +}; + +#[derive(Debug, Args)] +#[command(author, version, about, long_about = None)] +pub struct Edit { + /// The password index. Check it from list command + index: NonZeroU64, + + #[arg(short, long)] + /// The new password name + name: Option, + #[arg(short, long)] + /// The new password username + username: Option, + #[arg(short, long)] + /// The new password + password: Option, + #[arg(short, long)] + /// The new password service + service: Option, + #[arg(short = 'o', long)] + /// The new password note + note: Option, +} + +impl RunCommand for Edit { + fn run(&self, mut password_manager: Passwords) -> PassrsResult<()> { + let index = self.index.get() as usize; + + if let Some(password) = password_manager.passwords.get_mut(index - 1) { + if self.name.is_none() + && self.username.is_none() + && self.password.is_none() + && self.service.is_none() + && self.note.is_none() + { + Err(PassrsError::Other( + "You must edit one option at least".to_owned(), + )) + } else { + *password = Password { + name: self.name.as_ref().unwrap_or(&password.name).to_string(), + username: self + .username + .as_ref() + .unwrap_or(&password.username) + .to_string(), + password: self + .password + .as_ref() + .unwrap_or(&password.password) + .to_string(), + service: self.service.as_ref().or(password.service.as_ref()).cloned(), + note: self.note.as_ref().or(password.note.as_ref()).cloned(), + }; + password_manager.try_export() + } + } else { + Err(PassrsError::InvalidPasswordIndex(format!( + "The index `{}` is greater than the passwords count {}", + self.index, + password_manager.passwords.len() + ))) + } + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 3ba8a0b..292af26 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -25,6 +25,7 @@ use crate::{ pub mod add_command; pub mod clean_command; +pub mod edit_command; pub mod list_command; crate::create_commands!( @@ -32,8 +33,8 @@ crate::create_commands!( "Add new password", Add => add_command::Add "List your password and search", List => list_command::List "Clean the password file", Clean => clean_command::Clean - // TODO: Edit command - // TODO: Delete command + "Edit the password content", Edit => edit_command::Edit + // TODO: Remove command // TODO: Export command // TODO: Import command ); diff --git a/src/errors.rs b/src/errors.rs index eddf2e4..05d6265 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -34,6 +34,10 @@ pub enum Error { WeakPassword(String), #[error("Args Conflict Error: {0}")] ArgsConflict(String), + #[error("Invalid Password Index Error: {0}")] + InvalidPasswordIndex(String), + #[error("{0}")] + Other(String), #[error("Invalid Regex: {0}")] InvalidRegex(#[from] regex::Error),