From 2a05254415ace0a9731043876ad3f20119ea76f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Kozachuk Date: Wed, 14 Dec 2022 15:12:36 +0100 Subject: [PATCH] Allow to enter regular expression as argument to ls command, to get only matching passwords. --- src/parser.rs | 2 +- src/repl.rs | 21 ++++++++++++++------- src/structs.rs | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 4181544..05910e0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -72,7 +72,7 @@ peg::parser! { rule mode() -> Mode = m:(umode() / rmode()) { m } rule help_cmd() -> Command<'input> = "help" { Command::Help } rule quit_cmd() -> Command<'input> = "quit" { Command::Quit } - rule ls_cmd() -> Command<'input> = "ls" { Command::Ls } + rule ls_cmd() -> Command<'input> = "ls" f:comment()? { Command::Ls(f.unwrap_or(".".to_string())) } rule add_cmd() -> Command<'input> = "add" _ name:name() { Command::Add(Rc::new(RefCell::new(name))) } rule error_cmd() -> Command<'input> = "error" _ e:$(([' '..='~'])+) { Command::Error(LKErr::Error(e)) } rule mv_cmd() -> Command<'input> = "mv" _ name:word() _ folder:word() { Command::Mv(name, folder) } diff --git a/src/repl.rs b/src/repl.rs index efb42df..82ccbc0 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -1,6 +1,7 @@ use home::home_dir; use rpassword::prompt_password; use rustyline::Editor; +use regex::Regex; use std::{cell::RefCell, rc::Rc}; use crate::lk::LK; @@ -173,10 +174,16 @@ impl<'a> LKEval<'a> { }; } - fn cmd_ls(&self, out: &mut Vec) { + fn cmd_ls(&self, out: &mut Vec, filter: String) { + let re = match Regex::new(&filter) { + Ok(re) => re, + Err(e) => { out.push(format!("error: failed to parse re: {:?}", e)); return; } + }; let mut tmp: Vec = vec![]; for (_, name) in &self.state.borrow().db { - tmp.push(name.clone()); + if re.find(&name.borrow().to_string()).is_some() { + tmp.push(name.clone()); + } } tmp.sort_by(|a, b| a.borrow().name.cmp(&b.borrow().name)); self.state.borrow_mut().ls.clear(); @@ -198,7 +205,7 @@ impl<'a> LKEval<'a> { out.push("Bye!".to_string()); quit = true; } - Command::Ls => self.cmd_ls(&mut out), + Command::Ls(filter) => self.cmd_ls(&mut out, filter.to_string()), Command::Add(name) => { if self.state.borrow().db.get(&name.borrow().name).is_some() { out.push("error: password already exist".to_string()); @@ -290,7 +297,7 @@ mod tests { #[test] fn exec_cmds_basic() { let lk = Rc::new(RefCell::new(LK::new())); - assert_eq!(LKEval::news(Command::Ls, lk.clone()).eval(), LKPrint::new(vec![], false, lk.clone())); + assert_eq!(LKEval::news(Command::Ls(".".to_string()), lk.clone()).eval(), LKPrint::new(vec![], false, lk.clone())); let pwd1 = Rc::new(RefCell::new(Password { name: Rc::new("t1".to_string()), prefix: None, @@ -306,7 +313,7 @@ mod tests { db.insert(pwd1.borrow().name.clone(), pwd1.clone()); db }); - assert_eq!(LKEval::news(Command::Ls, lk.clone()).eval(), LKPrint::new(vec![" 1 t1 R 99 2022-12-30 comment".to_string()], false, lk.clone())); + assert_eq!(LKEval::news(Command::Ls(".".to_string()), lk.clone()).eval(), LKPrint::new(vec![" 1 t1 R 99 2022-12-30 comment".to_string()], false, lk.clone())); assert_eq!(LKEval::news(Command::Quit, lk.clone()).eval(), LKPrint::new(vec!["Bye!".to_string()], true, lk.clone())); let pwd2 = Rc::new(RefCell::new(Password { name: Rc::new("t2".to_string()), @@ -325,11 +332,11 @@ mod tests { db }); assert_eq!( - LKEval::news(Command::Ls, lk.clone()).eval(), + LKEval::news(Command::Ls(".".to_string()), lk.clone()).eval(), LKPrint::new(vec![" 1 t1 R 99 2022-12-30 comment".to_string(), " 2 t2 R 99 2022-12-31 bli blup".to_string()], false, lk.clone()) ); assert_eq!(LKEval::news(Command::Rm("2".to_string()), lk.clone()).eval(), LKPrint::new(vec!["removed t2".to_string()], false, lk.clone())); - assert_eq!(LKEval::news(Command::Ls, lk.clone()).eval(), LKPrint::new(vec![" 1 t1 R 99 2022-12-30 comment".to_string()], false, lk.clone())); + assert_eq!(LKEval::news(Command::Ls(".".to_string()), lk.clone()).eval(), LKPrint::new(vec![" 1 t1 R 99 2022-12-30 comment".to_string()], false, lk.clone())); } #[test] diff --git a/src/structs.rs b/src/structs.rs index 265f334..235c800 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -14,7 +14,7 @@ pub enum LKErr<'a> { #[derive(PartialEq, Debug)] pub enum Command<'a> { Add(PasswordRef), - Ls, + Ls(String), Mv(Name, Name), Rm(Name), Enc(Name),