diff --git a/src/main.rs b/src/main.rs index a365ce3..d01b97e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,11 @@ use std::io::{self, Write}; use std::process; +const VERSION: &str = "0.0.1"; + + #[derive(Parser)] -#[command(name = "mps", version = "0.0.1", about = "MyPasswordStorage: Tool for storing your passwords locally with git synchronization")] +#[command(name = "mps", version = VERSION, about = "MyPasswordStorage: Tool for storing your passwords locally with git synchronization")] struct Cli { #[command(subcommand)] command: Option, @@ -32,8 +35,13 @@ enum Commands { /// Show content of an item Show { - #[arg(value_name="item_id")] - id: String + // positional + #[arg(value_name="item_id", required=false)] + id: Option, + + // named + #[arg(short, long, value_name="item_number", required=false)] + number: Option }, /// Adds new item with unique id to the storage @@ -44,8 +52,13 @@ enum Commands { /// Edit item content Edit { - #[arg(value_name="item_id")] - id: String + // positional + #[arg(value_name="item_id", required=false)] + id: Option, + + // named + #[arg(short, long, value_name="item_number", required=false)] + number: Option }, Delete { @@ -149,13 +162,13 @@ impl MPS { fn list(&mut self) -> io:: Result<()> { self.login()?; let ids = self.storage.as_ref().unwrap().ids(); - // let mut counter = 1; + let mut counter = 1; if ids.len() == 0 { println!("No items"); } else { for id in ids { - println!("{}", id); - //counter += 1; + println!("[{}] {}", counter, id); + counter += 1; } } Ok(()) @@ -175,6 +188,13 @@ impl MPS { Ok(()) } + fn show_by_number(&mut self, number: u32) -> io::Result<()> { + self.login()?; + let st = self.storage.as_ref().unwrap(); + let id = st.get_id_by_number(number)?; + self.show(&id) + } + fn add(&mut self, id: &String) -> io::Result<()> { self.login()?; let st = self.storage.as_mut().unwrap(); @@ -216,6 +236,13 @@ impl MPS { Ok(()) } + fn edit_by_number(&mut self, number: u32) -> io::Result<()> { + self.login()?; + let st = self.storage.as_mut().unwrap(); + let id = st.get_id_by_number(number)?; + self.edit(&id) + } + fn delete(&mut self, id: &String) -> io::Result<()> { self.login()?; let st = self.storage.as_mut().unwrap(); @@ -242,17 +269,57 @@ fn run_command() -> io::Result<()> { let mut mps = MPS::new(); mps.list()?; } - Some(Commands::Show { id }) => { - let mut mps = MPS::new(); - mps.show(id)?; + Some(Commands::Show { id, number }) => { + match (id, number) { + (None, None) => { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Must provide or -n " + )); + } + (Some(item_id), None) => { + let mut mps = MPS::new(); + mps.show(item_id)?; + }, + (None, Some(item_number)) => { + let mut mps = MPS::new(); + mps.show_by_number(*item_number)?; + }, + _ => { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Must provide or -n but not both" + )) + } + }; } Some(Commands::Add { id }) => { let mut mps = MPS::new(); mps.add(id)?; } - Some(Commands::Edit { id }) => { - let mut mps = MPS::new(); - mps.edit(id)? + Some(Commands::Edit { id, number }) => { + match (id, number) { + (None, None) => { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Must provide or -n " + )); + } + (Some(item_id), None) => { + let mut mps = MPS::new(); + mps.edit(item_id)?; + }, + (None, Some(item_number)) => { + let mut mps = MPS::new(); + mps.edit_by_number(*item_number)?; + }, + _ => { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Must provide or -n but not both" + )) + } + }; } Some(Commands::Delete { id }) => { let mut mps = MPS::new(); diff --git a/src/storage.rs b/src/storage.rs index 7d78344..db6e4b8 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -180,11 +180,31 @@ impl Storage { let item = Item::from_empty(id.clone()); self.items.contains(&item) } - + + // TODO: return Result pub fn get(&self, id: &String) -> &Item { let item = Item::from_empty(id.clone()); self.items.get(&item).unwrap() } + + /// Counting starts from 1, according to UI + pub fn get_id_by_number(&self, number: u32) -> io::Result { + let number = number as usize; + if number == 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "Items numbering starts from 1" + )); + } + let ids = self.ids(); + if number >= ids.len() { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + format!("There are only {} items, but asked with number {}", ids.len(), number) + )); + } + Ok(ids[number - 1].clone()) + } pub fn add(&mut self, item: Item) { self.items.insert(item);