diff --git a/src/lk.rs b/src/lk.rs index 26553f4..73fcc2b 100644 --- a/src/lk.rs +++ b/src/lk.rs @@ -1,7 +1,7 @@ use std::{cell::RefCell, rc::Rc}; use std::collections::HashMap; use regex::{Regex, Captures}; -use crate::structs::Password; +use crate::structs::{Password, fix_password_recursion}; #[derive(PartialEq, Debug)] pub struct LK { @@ -9,6 +9,10 @@ pub struct LK { } impl LK { + pub fn new() -> Self { + Self { db: HashMap::new() } + } + pub fn fix_hierarchy(&self) { lazy_static! { static ref RE: Regex = Regex::new(r"\s*\^([!-~]+)").unwrap(); @@ -22,17 +26,16 @@ impl LK { let folder_name = folder.unwrap(); for (_, entry) in &self.db { if *entry.borrow().name == *folder_name { - { - let mut tmp = name.borrow_mut(); - tmp.parent = Some(entry.clone()); - if comment.len() == 0 { tmp.comment = None } - else { tmp.comment = Some(comment.to_string()) } - } + let mut tmp = name.borrow_mut(); + tmp.parent = Some(entry.clone()); + if comment.len() == 0 { tmp.comment = None } + else { tmp.comment = Some(comment.to_string()) } break; } } } } + fix_password_recursion(name.clone()); } } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index c787ac0..24328a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,15 +7,13 @@ mod repl; mod lk; use std::{cell::RefCell, rc::Rc}; -use std::collections::HashMap; - use rustyline::Editor; use crate::lk::LK; use crate::repl::LKRead; pub fn main() { - let lk = Rc::new(RefCell::new(LK { db: HashMap::new() })); + let lk = Rc::new(RefCell::new(LK::new())); let mut lkread = LKRead::new( Editor::<()>::new().unwrap(), String::from("❯ "), @@ -25,4 +23,4 @@ pub fn main() { lkread.refresh(); } lkread.quit(); -} \ No newline at end of file +} diff --git a/src/parser.rs b/src/parser.rs index e5adbe0..e30c214 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -126,4 +126,4 @@ mod tests { length: Some(20), seq: 99, date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(), comment: Some("a b c".to_string()) })); } -} \ No newline at end of file +} diff --git a/src/repl.rs b/src/repl.rs index 19a3501..72a3d34 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc}; use home::home_dir; use crate::lk::LK; -use crate::structs::{LKErr, Command}; +use crate::structs::{LKErr, Command, fix_password_recursion}; use crate::parser::command_parser; #[derive(Debug)] @@ -77,6 +77,7 @@ impl<'a> LKEval<'a> { for (_, name) in &self.state.borrow().db { out.push(name.borrow().to_string()); } + out.sort(); }, Command::Add(name) => { if self.state.borrow().db.get(&name.borrow().name).is_some() { @@ -97,6 +98,7 @@ impl<'a> LKEval<'a> { for (_, fld) in &self.state.borrow().db { if *fld.borrow().name == *folder { tmp.borrow_mut().parent = Some(fld.clone()); + fix_password_recursion(tmp.clone()); break; } } @@ -138,7 +140,7 @@ mod tests { #[test] fn exec_cmds_basic() { - let lk = Rc::new(RefCell::new(LK { db: HashMap::new() })); + let lk = Rc::new(RefCell::new(LK::new())); assert_eq!(LKEval::new(Command::Ls, lk.clone()).eval(), LKPrint::new(vec![], false, lk.clone())); let pwd1 = Rc::new(RefCell::new(Password { name: Rc::new("t1".to_string()), prefix: None, length: None, @@ -151,9 +153,9 @@ mod tests { db.insert(pwd1.borrow().name.clone(), pwd1.clone()); db }); assert_eq!(LKEval::new(Command::Ls, lk.clone()).eval(), - LKPrint::new(vec!["t1 R 99 2022-12-30 comment"], false, lk.clone())); + LKPrint::new(vec!["t1 R 99 2022-12-30 comment".to_string()], false, lk.clone())); assert_eq!(LKEval::new(Command::Quit, lk.clone()).eval(), - LKPrint::new(vec!["Bye"], true, lk.clone())); + LKPrint::new(vec!["Bye!".to_string()], true, lk.clone())); let pwd2 = Rc::new(RefCell::new(Password { name: Rc::new("t2".to_string()), prefix: None, length: None, mode: Mode::Regular, seq: 99, @@ -166,7 +168,8 @@ mod tests { db.insert(pwd2.borrow().name.clone(), pwd2.clone()); db }); assert_eq!(LKEval::new(Command::Ls, lk.clone()).eval(), - LKPrint::new(vec!["t1 R 99 2022-12-30 comment", - "t2 R 99 2022-12-31 bli blup"], false, lk.clone())); + LKPrint::new(vec!["t1 R 99 2022-12-30 comment".to_string(), + "t2 R 99 2022-12-31 bli blup".to_string()], + false, lk.clone())); } -} \ No newline at end of file +} diff --git a/src/structs.rs b/src/structs.rs index 399ebe1..389ef81 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -62,6 +62,34 @@ impl std::fmt::Display for Mode { } } +impl Password { + pub fn new(prefix: Option, name: String, mode: Mode, date: NaiveDate) -> Password { + Password { prefix, mode, date, + parent: None, + name: Rc::new(name), + length: None, + seq: 99, + comment: None } + } +} + +pub fn fix_password_recursion(entry: Rc>) { + let mut t1 = entry.clone(); + let mut t2 = entry; + let mut t3: Option>> = None; + loop { + t2 = match &t2.clone().borrow().parent { Some(o) => o.clone(), None => break }; + if std::ptr::eq((*t1).as_ptr(), (*t2).as_ptr()) { t3 = Some(t1.clone()); break; } + t1 = match &t1.clone().borrow().parent { Some(o) => o.clone(), None => break }; + t2 = match &t2.clone().borrow().parent { Some(o) => o.clone(), None => break }; + if std::ptr::eq((*t1).as_ptr(), (*t2).as_ptr()) { t3 = Some(t1.clone()); break; } + } + match t3 { + Some(o) => o.borrow_mut().parent = None, + None => (), + } +} + impl std::string::ToString for Password { fn to_string(&self) -> String { let prefix = match self.prefix.as_ref() { Some(s) => format!("{} ", s), None => "".to_string() }; @@ -71,3 +99,30 @@ impl std::string::ToString for Password { format!("{}{} {}{} {} {}{}{}", prefix, self.name, length, self.mode, self.seq, self.date, comment, parent) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn exec_recursion_test() { + let p1 = Rc::new(RefCell::new(Password::new(None, "p1".to_string(), Mode::Regular, NaiveDate::from_ymd_opt(2022, 12, 3).unwrap()))); + + p1.borrow_mut().parent = Some(p1.clone()); + fix_password_recursion(p1.clone()); + assert_eq!(p1.borrow().parent, None); + + let p2 = Rc::new(RefCell::new(Password::new(None, "p2".to_string(), Mode::Regular, NaiveDate::from_ymd_opt(2022, 12, 3).unwrap()))); + p2.borrow_mut().parent = Some(p1.clone()); + let p3 = Rc::new(RefCell::new(Password::new(None, "p3".to_string(), Mode::Regular, NaiveDate::from_ymd_opt(2022, 12, 3).unwrap()))); + p3.borrow_mut().parent = Some(p2.clone()); + let p4 = Rc::new(RefCell::new(Password::new(None, "p4".to_string(), Mode::Regular, NaiveDate::from_ymd_opt(2022, 12, 3).unwrap()))); + p4.borrow_mut().parent = Some(p3.clone()); + let p5 = Rc::new(RefCell::new(Password::new(None, "p5".to_string(), Mode::Regular, NaiveDate::from_ymd_opt(2022, 12, 3).unwrap()))); + p5.borrow_mut().parent = Some(p4.clone()); + + p1.borrow_mut().parent = Some(p3.clone()); + fix_password_recursion(p5.clone()); + assert_eq!(p3.borrow().parent, None); + } +}