Switch from Rc<RefCell> to Arc<Mutex<T>> or Arc<ReentrantMutex<RefCell<T>>>.
This commit is contained in:
+76
-71
@@ -11,14 +11,14 @@ use crate::password::fix_password_recursion;
|
||||
use crate::password::{Name, Password, PasswordRef};
|
||||
use crate::repl::LKEval;
|
||||
use crate::structs::{LKOut, Radix, CORRECT_FILE, DUMP_FILE};
|
||||
use crate::utils::{call_cmd_with_input, get_cmd_args_from_command, get_copy_command_from_env, rnd};
|
||||
use crate::utils::editor::password;
|
||||
use crate::utils::{call_cmd_with_input, get_cmd_args_from_command, get_copy_command_from_env, rnd};
|
||||
|
||||
impl<'a> LKEval<'a> {
|
||||
pub fn get_password(&self, name: &String) -> Option<PasswordRef> {
|
||||
match self.state.borrow().ls.get(name) {
|
||||
match self.state.lock().borrow().ls.get(name) {
|
||||
Some(pwd) => Some(pwd.clone()),
|
||||
None => match self.state.borrow().db.get(name) {
|
||||
None => match self.state.lock().borrow().db.get(name) {
|
||||
Some(pwd) => Some(pwd.clone()),
|
||||
None => None,
|
||||
},
|
||||
@@ -34,15 +34,15 @@ impl<'a> LKEval<'a> {
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
let parent = match &pwd.borrow().parent {
|
||||
Some(p) => p.borrow().name.to_string(),
|
||||
let parent = match &pwd.lock().borrow().parent {
|
||||
Some(p) => p.lock().borrow().name.to_string(),
|
||||
None => "/".to_string(),
|
||||
};
|
||||
let secret = match self.state.borrow().secrets.get(&parent) {
|
||||
let secret = match self.state.lock().borrow().secrets.get(&parent) {
|
||||
Some(p) => Some(p.clone()),
|
||||
None => None,
|
||||
};
|
||||
match (pwd.borrow().parent.clone(), secret) {
|
||||
match (pwd.lock().borrow().parent.clone(), secret) {
|
||||
(_, Some(s)) => Some(s.to_string()),
|
||||
(None, None) => {
|
||||
if read {
|
||||
@@ -50,7 +50,7 @@ impl<'a> LKEval<'a> {
|
||||
Ok(password) => {
|
||||
let name = "/".to_string();
|
||||
self.cmd_correct(&out, &name, true, Some(password.clone()));
|
||||
self.state.borrow_mut().secrets.insert(name, password.clone());
|
||||
self.state.lock().borrow_mut().secrets.insert(name, password.clone());
|
||||
Some(password)
|
||||
}
|
||||
Err(_) => None,
|
||||
@@ -61,22 +61,22 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
(Some(pn), None) => {
|
||||
let password = if read {
|
||||
(self.read_password)(format!("Password for {}: ", pn.borrow().name)).ok()
|
||||
(self.read_password)(format!("Password for {}: ", pn.lock().borrow().name)).ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if password.is_some() && password.as_ref().unwrap().len() > 0 {
|
||||
let name = pn.borrow().name.to_string();
|
||||
let name = pn.lock().borrow().name.to_string();
|
||||
self.cmd_correct(&out, &name, true, Some(password.as_ref().unwrap().clone()));
|
||||
self.state.borrow_mut().secrets.insert(name, password.as_ref().unwrap().clone());
|
||||
self.state.lock().borrow_mut().secrets.insert(name, password.as_ref().unwrap().clone());
|
||||
password
|
||||
} else {
|
||||
match self.read_master(&out, pn.clone(), read) {
|
||||
Some(master) => {
|
||||
let password = pn.borrow().encode(master.as_str());
|
||||
let name = pn.borrow().name.to_string();
|
||||
let password = pn.lock().borrow().encode(master.as_str());
|
||||
let name = pn.lock().borrow().name.to_string();
|
||||
self.cmd_correct(&out, &name, true, Some(password.to_string()));
|
||||
self.state.borrow_mut().secrets.insert(name, password.clone());
|
||||
self.state.lock().borrow_mut().secrets.insert(name, password.clone());
|
||||
Some(password)
|
||||
}
|
||||
None => None,
|
||||
@@ -87,15 +87,15 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
|
||||
pub fn cmd_add(&self, out: &LKOut, name: &PasswordRef) {
|
||||
let state = &mut self.state.borrow_mut();
|
||||
let state_cell = self.state.lock();
|
||||
let mut state = state_cell.borrow_mut();
|
||||
let mut fix = false;
|
||||
{
|
||||
let db = &mut state.db;
|
||||
let pwname = &name.borrow().name.to_string();
|
||||
if db.get(pwname).is_some() {
|
||||
let pwname = &name.lock().borrow().name.to_string();
|
||||
if state.db.get(pwname).is_some() {
|
||||
out.e(format!("error: password {} already exist", pwname));
|
||||
} else {
|
||||
db.insert(pwname.to_string(), name.clone());
|
||||
state.db.insert(pwname.to_string(), name.clone());
|
||||
fix = true;
|
||||
}
|
||||
}
|
||||
@@ -105,9 +105,12 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
|
||||
pub fn cmd_leave(&self, out: &LKOut, name: &Name) {
|
||||
let pwd = match self.state.borrow().ls.get(name) {
|
||||
let pwd = match self.state.lock().borrow().ls.get(name) {
|
||||
Some(pwd) => pwd.clone(),
|
||||
None => { out.e(format!("error: {} not found", name)); return; }
|
||||
None => {
|
||||
out.e(format!("error: {} not found", name));
|
||||
return;
|
||||
}
|
||||
};
|
||||
self.cmd_add(&out, &pwd);
|
||||
}
|
||||
@@ -116,11 +119,11 @@ impl<'a> LKEval<'a> {
|
||||
match self.get_password(name) {
|
||||
Some(pwd) => {
|
||||
if folder == "/" {
|
||||
pwd.borrow_mut().parent = None
|
||||
pwd.lock().borrow_mut().parent = None
|
||||
} else {
|
||||
match self.get_password(folder) {
|
||||
Some(fld) => {
|
||||
pwd.borrow_mut().parent = Some(fld.clone());
|
||||
pwd.lock().borrow_mut().parent = Some(fld.clone());
|
||||
fix_password_recursion(pwd.clone());
|
||||
}
|
||||
None => out.e(format!("error: folder {} not found", folder)),
|
||||
@@ -134,18 +137,15 @@ impl<'a> LKEval<'a> {
|
||||
pub fn cmd_pass(&self, out: &LKOut, name: &String) {
|
||||
match self.get_password(name) {
|
||||
Some(p) => {
|
||||
let pwd = (self.read_password)(format!("Password for {}: ", p.borrow().name)).unwrap();
|
||||
self.cmd_correct(&out, &p.borrow().name, true, Some(pwd.clone()));
|
||||
self.state.borrow_mut().secrets.insert(p.borrow().name.to_string(), pwd);
|
||||
let pwd = (self.read_password)(format!("Password for {}: ", p.lock().borrow().name)).unwrap();
|
||||
self.cmd_correct(&out, &p.lock().borrow().name, true, Some(pwd.clone()));
|
||||
self.state.lock().borrow_mut().secrets.insert(p.lock().borrow().name.to_string(), pwd);
|
||||
}
|
||||
None => {
|
||||
if name == "/" {
|
||||
let pwd = (self.read_password)("Master: ".to_string()).unwrap();
|
||||
self.cmd_correct(&out, &"/".to_string(), true, Some(pwd.clone()));
|
||||
self.state
|
||||
.borrow_mut()
|
||||
.secrets
|
||||
.insert("/".to_string(), pwd);
|
||||
self.state.lock().borrow_mut().secrets.insert("/".to_string(), pwd);
|
||||
} else {
|
||||
out.e(format!("error: password with name {} not found", name));
|
||||
}
|
||||
@@ -156,7 +156,7 @@ impl<'a> LKEval<'a> {
|
||||
pub fn cmd_comment(&self, out: &LKOut, name: &String, comment: &Option<String>) {
|
||||
match self.get_password(name) {
|
||||
Some(pwd) => {
|
||||
pwd.borrow_mut().comment = match comment {
|
||||
pwd.lock().borrow_mut().comment = match comment {
|
||||
Some(c) => Some(c.to_string()),
|
||||
None => None,
|
||||
}
|
||||
@@ -167,8 +167,8 @@ impl<'a> LKEval<'a> {
|
||||
|
||||
pub fn cmd_enc(&self, out: &LKOut, name: &String) -> Option<(String, String)> {
|
||||
let root_folder = "/".to_string();
|
||||
let (name, pass) = if name == "/" && self.state.borrow().secrets.contains_key(&root_folder) {
|
||||
(root_folder.to_string(), self.state.borrow().secrets.get(&root_folder).unwrap().to_string())
|
||||
let (name, pass) = if name == "/" && self.state.lock().borrow().secrets.contains_key(&root_folder) {
|
||||
(root_folder.to_string(), self.state.lock().borrow().secrets.get(&root_folder).unwrap().to_string())
|
||||
} else {
|
||||
let pwd = match self.get_password(name) {
|
||||
Some(p) => p.clone(),
|
||||
@@ -177,12 +177,12 @@ impl<'a> LKEval<'a> {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let name = pwd.borrow().name.to_string();
|
||||
if self.state.borrow().secrets.contains_key(&name) {
|
||||
(name.clone(), self.state.borrow().secrets.get(&name).unwrap().to_string())
|
||||
let name = pwd.lock().borrow().name.to_string();
|
||||
if self.state.lock().borrow().secrets.contains_key(&name) {
|
||||
(name.clone(), self.state.lock().borrow().secrets.get(&name).unwrap().to_string())
|
||||
} else {
|
||||
match self.read_master(&out, pwd.clone(), true) {
|
||||
Some(sec) => (name.clone(), pwd.borrow().encode(sec.as_str())),
|
||||
Some(sec) => (name.clone(), pwd.lock().borrow().encode(sec.as_str())),
|
||||
None => {
|
||||
out.e(format!("error: master for {} not found", name));
|
||||
return None;
|
||||
@@ -253,7 +253,9 @@ impl<'a> LKEval<'a> {
|
||||
for cmd in cmd_list {
|
||||
let print = LKEval::new(cmd, self.state.clone(), password).eval();
|
||||
print.out.copy(&out);
|
||||
if print.quit { return true; }
|
||||
if print.quit {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -273,9 +275,9 @@ impl<'a> LKEval<'a> {
|
||||
let file = fs::File::create(script)?;
|
||||
let mut writer = BufWriter::new(file);
|
||||
let mut vals = data.values().map(|v| v.clone()).collect::<Vec<PasswordRef>>();
|
||||
vals.sort_by(|a, b| a.borrow().name.cmp(&b.borrow().name));
|
||||
vals.sort_by(|a, b| a.lock().borrow().name.cmp(&b.lock().borrow().name));
|
||||
for pwd in vals {
|
||||
writeln!(writer, "add {}", pwd.borrow().to_string())?
|
||||
writeln!(writer, "add {}", pwd.lock().borrow().to_string())?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -289,10 +291,11 @@ impl<'a> LKEval<'a> {
|
||||
};
|
||||
let data = self
|
||||
.state
|
||||
.lock()
|
||||
.borrow()
|
||||
.db
|
||||
.values()
|
||||
.map(|v| format!("add {}", v.borrow().to_string()))
|
||||
.map(|v| format!("add {}", v.lock().borrow().to_string()))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
let output = match call_cmd_with_input(&cmd, &args, data.as_str()) {
|
||||
@@ -309,13 +312,13 @@ impl<'a> LKEval<'a> {
|
||||
out.o(format!("Passwords saved to command {}", cmd));
|
||||
}
|
||||
} else if script.trim() == "-" {
|
||||
let mut vals = (&self.state.borrow().db).values().map(|v| v.clone()).collect::<Vec<PasswordRef>>();
|
||||
vals.sort_by(|a, b| a.borrow().name.cmp(&b.borrow().name));
|
||||
let mut vals = (&self.state.lock().borrow().db).values().map(|v| v.clone()).collect::<Vec<PasswordRef>>();
|
||||
vals.sort_by(|a, b| a.lock().borrow().name.cmp(&b.lock().borrow().name));
|
||||
for pwd in vals {
|
||||
out.o(format!("add {}", pwd.borrow().to_string()))
|
||||
};
|
||||
out.o(format!("add {}", pwd.lock().borrow().to_string()))
|
||||
}
|
||||
} else {
|
||||
match save_dump(&self.state.borrow().db, &script) {
|
||||
match save_dump(&self.state.lock().borrow().db, &script) {
|
||||
Ok(()) => out.o(format!("Passwords saved to file {}", script)),
|
||||
Err(e) => out.e(format!("error: failed to dump passswords to {}: {}", script, e.to_string())),
|
||||
};
|
||||
@@ -334,24 +337,26 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
};
|
||||
let mut tmp: Vec<PasswordRef> = vec![];
|
||||
for (_, name) in &self.state.borrow().db {
|
||||
if re.find(&name.borrow().to_string()).is_some() {
|
||||
for (_, name) in &self.state.lock().borrow().db {
|
||||
if re.find(&name.lock().borrow().to_string()).is_some() {
|
||||
tmp.push(name.clone());
|
||||
} else if re.find(&name.borrow().name).is_some() {
|
||||
} else if re.find(&name.lock().borrow().name).is_some() {
|
||||
tmp.push(name.clone());
|
||||
} else if name.borrow().comment.is_some() && re.find(&name.borrow().comment.as_ref().unwrap()).is_some() {
|
||||
} else if name.lock().borrow().comment.is_some()
|
||||
&& re.find(&name.lock().borrow().comment.as_ref().unwrap()).is_some()
|
||||
{
|
||||
tmp.push(name.clone());
|
||||
}
|
||||
}
|
||||
tmp.sort_by(|a,b| a.borrow().name.cmp(&b.borrow().name));
|
||||
tmp.sort_by(|a, b| a.lock().borrow().name.cmp(&b.lock().borrow().name));
|
||||
tmp.sort_by(sort_by);
|
||||
self.state.borrow_mut().ls.clear();
|
||||
self.state.lock().borrow_mut().ls.clear();
|
||||
let mut counter = 1;
|
||||
for pwd in tmp {
|
||||
let key = Radix::new(counter, 36).unwrap().to_string();
|
||||
counter += 1;
|
||||
self.state.borrow_mut().ls.insert(key.clone(), pwd.clone());
|
||||
out.o(format!("{:>3} {}", key, pwd.borrow().to_string()));
|
||||
self.state.lock().borrow_mut().ls.insert(key.clone(), pwd.clone());
|
||||
out.o(format!("{:>3} {}", key, pwd.lock().borrow().to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,42 +440,42 @@ impl<'a> LKEval<'a> {
|
||||
static ref RE: Regex = Regex::new(r"^.+?(G+|X+)$").unwrap();
|
||||
}
|
||||
let num: usize = (*num).try_into().unwrap();
|
||||
let pwd = name.borrow();
|
||||
let pwd = name.lock();
|
||||
let mut genpwds: Vec<PasswordRef> = Vec::new();
|
||||
match RE.captures(pwd.name.as_ref()) {
|
||||
match RE.captures(pwd.borrow().name.as_ref()) {
|
||||
Some(caps) => {
|
||||
let gen = &caps[1];
|
||||
if gen.starts_with("G") {
|
||||
let name = pwd.name.trim_end_matches('G');
|
||||
let name = pwd.borrow().name.trim_end_matches('G').to_string();
|
||||
for num in 1..10_u32.pow(gen.len().try_into().unwrap()) {
|
||||
let npwd = Password::from_password(&pwd);
|
||||
npwd.borrow_mut().name = format!("{}{}", name, num).to_string();
|
||||
let npwd = Password::from_password_ref(&pwd.borrow());
|
||||
npwd.lock().borrow_mut().name = format!("{}{}", name, num).to_string();
|
||||
genpwds.push(npwd);
|
||||
}
|
||||
} else {
|
||||
let name = pwd.name.trim_end_matches('X');
|
||||
let name = pwd.borrow().name.trim_end_matches('X').to_string();
|
||||
let num = rnd::range(1, 10_u32.pow(gen.len().try_into().unwrap()));
|
||||
let npwd = Password::from_password(&pwd);
|
||||
npwd.borrow_mut().name = format!("{}{}", name, num).to_string();
|
||||
let npwd = Password::from_password_ref(&pwd.borrow());
|
||||
npwd.lock().borrow_mut().name = format!("{}{}", name, num).to_string();
|
||||
genpwds.push(npwd);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let npwd = Password::from_password(&pwd);
|
||||
let npwd = Password::from_password_ref(&pwd.borrow());
|
||||
genpwds.push(npwd);
|
||||
}
|
||||
}
|
||||
self.state.borrow_mut().ls.clear();
|
||||
self.state.lock().borrow_mut().ls.clear();
|
||||
let mut counter = 1;
|
||||
let mut lspwds: Vec<(PasswordRef, String)> = Vec::new();
|
||||
for num in 0..genpwds.len() {
|
||||
let pwd = genpwds[num].clone();
|
||||
let key = Radix::new(counter, 36).unwrap().to_string();
|
||||
counter += 1;
|
||||
self.state.borrow_mut().ls.insert(key.to_string(), pwd.clone());
|
||||
self.state.lock().borrow_mut().ls.insert(key.to_string(), pwd.clone());
|
||||
lspwds.push((pwd, key));
|
||||
}
|
||||
self.state.borrow().fix_hierarchy();
|
||||
self.state.lock().borrow().fix_hierarchy();
|
||||
let mut err = match &out.err {
|
||||
Some(e) => Some(e.clone()),
|
||||
None => None,
|
||||
@@ -479,8 +484,8 @@ impl<'a> LKEval<'a> {
|
||||
for (pwd, key) in lspwds {
|
||||
let pass = match self.cmd_enc(&LKOut::from_lkout(None, err), &key) {
|
||||
Some((name, pass)) => {
|
||||
if name != pwd.borrow().name {
|
||||
panic!("INTERNAL_ERROR: wrong name found: {} != {}", name, pwd.borrow().name);
|
||||
if name != pwd.lock().borrow().name {
|
||||
panic!("INTERNAL_ERROR: wrong name found: {} != {}", name, pwd.lock().borrow().name);
|
||||
};
|
||||
pass
|
||||
}
|
||||
@@ -493,15 +498,15 @@ impl<'a> LKEval<'a> {
|
||||
encpwds.push((pwd.clone(), pass));
|
||||
}
|
||||
encpwds.sort_by(|a, b| b.1.len().cmp(&a.1.len()));
|
||||
self.state.borrow_mut().ls.clear();
|
||||
self.state.lock().borrow_mut().ls.clear();
|
||||
let mut counter = 1;
|
||||
out.o(format!("{:>3} {:>36} {:>4} {}", "", "Password", "Len", "Name"));
|
||||
for num in (encpwds.len() - min(genpwds.len(), num))..encpwds.len() {
|
||||
let (pwd, pass) = (encpwds[num].0.clone(), encpwds[num].1.to_string());
|
||||
let key = Radix::new(counter, 36).unwrap().to_string();
|
||||
counter += 1;
|
||||
self.state.borrow_mut().ls.insert(key.clone(), pwd.clone());
|
||||
out.o(format!("{:>3} {:>36} {:>4} {}", key, pass, pass.len(), pwd.borrow().to_string()));
|
||||
self.state.lock().borrow_mut().ls.insert(key.clone(), pwd.clone());
|
||||
out.o(format!("{:>3} {:>36} {:>4} {}", key, pass, pass.len(), pwd.lock().borrow().to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,4 +12,3 @@ pub mod repl;
|
||||
pub mod skey;
|
||||
pub mod structs;
|
||||
pub mod utils;
|
||||
|
||||
|
||||
+28
-4
@@ -1,8 +1,13 @@
|
||||
use crate::password::{fix_password_recursion, Name, PasswordRef};
|
||||
use parking_lot::ReentrantMutex;
|
||||
use regex::{Captures, Regex};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub type LKRef = Arc<ReentrantMutex<RefCell<LK>>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LK {
|
||||
pub db: HashMap<Name, PasswordRef>,
|
||||
pub ls: HashMap<String, PasswordRef>,
|
||||
@@ -24,7 +29,7 @@ impl LK {
|
||||
}
|
||||
for db in vec![&self.db, &self.ls] {
|
||||
for (_, name) in db {
|
||||
let comment = name.borrow().comment.clone();
|
||||
let comment = name.lock().borrow().comment.clone();
|
||||
match comment {
|
||||
Some(comment) => {
|
||||
let mut changed = false;
|
||||
@@ -33,7 +38,7 @@ impl LK {
|
||||
let folder = c[1].to_string();
|
||||
match self.db.get(&folder) {
|
||||
Some(entry) => {
|
||||
name.borrow_mut().parent = Some(entry.clone());
|
||||
name.lock().borrow_mut().parent = Some(entry.clone());
|
||||
changed = true;
|
||||
}
|
||||
None => (),
|
||||
@@ -43,7 +48,7 @@ impl LK {
|
||||
.trim()
|
||||
.to_string();
|
||||
if changed && new != comment {
|
||||
name.borrow_mut().comment = if new.len() > 0 { Some(new) } else { None }
|
||||
name.lock().borrow_mut().comment = if new.len() > 0 { Some(new) } else { None }
|
||||
}
|
||||
}
|
||||
None => (),
|
||||
@@ -53,3 +58,22 @@ impl LK {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for LK {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.db.len() != other.db.len() || self.ls.len() != other.ls.len() || self.secrets != other.secrets {
|
||||
return false;
|
||||
}
|
||||
for (k, v) in &self.db {
|
||||
if !other.db.contains_key(k) || *other.db[k].lock() != *v.lock() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (k, v) in &self.ls {
|
||||
if !other.ls.contains_key(k) || *other.ls[k].lock() != *v.lock() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
+20
-21
@@ -3,7 +3,6 @@ extern crate peg;
|
||||
use crate::password::Password;
|
||||
use crate::structs::{Command, LKErr, Mode};
|
||||
use crate::utils::date::Date;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
peg::parser! {
|
||||
pub grammar command_parser() for str {
|
||||
@@ -89,10 +88,10 @@ peg::parser! {
|
||||
rule source_cmd() -> Command<'input> = "source" _ s:$(([' '..='~'])+) { Command::Source(s.to_string()) }
|
||||
rule ls_cmd() -> Command<'input> = "ls" f:comment()? { Command::Ls(f.unwrap_or(".".to_string())) }
|
||||
rule ld_cmd() -> Command<'input> = "ld" f:comment()? { Command::Ld(f.unwrap_or(".".to_string())) }
|
||||
rule add_cmd() -> Command<'input> = "add" _ name:name() { Command::Add(Rc::new(RefCell::new(name))) }
|
||||
rule add_cmd() -> Command<'input> = "add" _ name:name() { Command::Add(Password::from_password(name)) }
|
||||
rule leave_cmd() -> Command<'input> = "leave" _ name:word() { Command::Leave(name.to_string()) }
|
||||
rule gen_cmd() -> Command<'input> = "gen" n:num()? _ name:name() {
|
||||
Command::Gen(match n { Some(n) => n, None => 10_u32 }, Rc::new(RefCell::new(name)))
|
||||
Command::Gen(match n { Some(n) => n, None => 10_u32 }, Password::from_password(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) }
|
||||
@@ -119,7 +118,7 @@ add t2 C 99 2022-12-14
|
||||
add t3 C 99 2022-12-14"###
|
||||
),
|
||||
Ok(vec![
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t1".to_string(),
|
||||
@@ -128,8 +127,8 @@ add t3 C 99 2022-12-14"###
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
})),
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t2".to_string(),
|
||||
@@ -138,8 +137,8 @@ add t3 C 99 2022-12-14"###
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
})),
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t3".to_string(),
|
||||
@@ -148,7 +147,7 @@ add t3 C 99 2022-12-14"###
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
})))
|
||||
}))
|
||||
])
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -159,7 +158,7 @@ add t3 C 99 2022-12-14
|
||||
"###
|
||||
),
|
||||
Ok(vec![
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t1".to_string(),
|
||||
@@ -168,8 +167,8 @@ add t3 C 99 2022-12-14
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
})),
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t2".to_string(),
|
||||
@@ -178,8 +177,8 @@ add t3 C 99 2022-12-14
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
})),
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t3".to_string(),
|
||||
@@ -188,7 +187,7 @@ add t3 C 99 2022-12-14
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
})),
|
||||
Command::Noop
|
||||
])
|
||||
);
|
||||
@@ -201,7 +200,7 @@ add t3 C 99 2022-12-14
|
||||
"###
|
||||
),
|
||||
Ok(vec![
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t1".to_string(),
|
||||
@@ -210,8 +209,8 @@ add t3 C 99 2022-12-14
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
})),
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t2".to_string(),
|
||||
@@ -220,8 +219,8 @@ add t3 C 99 2022-12-14
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
Command::Add(Rc::new(RefCell::new(Password {
|
||||
})),
|
||||
Command::Add(Password::from_password(Password {
|
||||
parent: None,
|
||||
prefix: None,
|
||||
name: "t3".to_string(),
|
||||
@@ -230,7 +229,7 @@ add t3 C 99 2022-12-14
|
||||
seq: 99,
|
||||
date: Date::new(2022, 12, 14),
|
||||
comment: None
|
||||
}))),
|
||||
})),
|
||||
Command::Noop,
|
||||
Command::Noop
|
||||
])
|
||||
|
||||
+56
-33
@@ -1,17 +1,19 @@
|
||||
use crate::skey::SKey;
|
||||
use crate::structs::Mode;
|
||||
use crate::utils::date::Date;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use parking_lot::ReentrantMutex;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub type Name = String;
|
||||
pub type Prefix = Option<String>;
|
||||
pub type Comment = Option<String>;
|
||||
pub type PasswordRef = Rc<RefCell<Password>>;
|
||||
pub type PasswordRef = Arc<ReentrantMutex<RefCell<Password>>>;
|
||||
pub type Parent = Option<PasswordRef>;
|
||||
pub type Length = Option<u32>;
|
||||
pub type Seq = u32;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub struct Password {
|
||||
pub parent: Parent,
|
||||
pub prefix: Prefix,
|
||||
@@ -45,8 +47,8 @@ impl Password {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_password(password: &Password) -> PasswordRef {
|
||||
Rc::new(RefCell::new(Self {
|
||||
pub fn from_password_ref(password: &Password) -> PasswordRef {
|
||||
Arc::new(ReentrantMutex::new(RefCell::new(Self {
|
||||
parent: password.parent.clone(),
|
||||
prefix: password.prefix.clone(),
|
||||
name: password.name.clone(),
|
||||
@@ -55,7 +57,11 @@ impl Password {
|
||||
seq: password.seq,
|
||||
date: password.date.clone(),
|
||||
comment: password.comment.clone(),
|
||||
}))
|
||||
})))
|
||||
}
|
||||
|
||||
pub fn from_password(password: Password) -> PasswordRef {
|
||||
Arc::new(ReentrantMutex::new(RefCell::new(password)))
|
||||
}
|
||||
|
||||
pub fn encode(&self, secret: &str) -> String {
|
||||
@@ -109,13 +115,28 @@ impl std::string::ToString for Password {
|
||||
None => "".to_string(),
|
||||
};
|
||||
let parent = match &self.parent {
|
||||
Some(s) => format!(" ^{}", s.borrow().name),
|
||||
Some(s) => format!(" ^{}", s.lock().borrow().name),
|
||||
None => "".to_string(),
|
||||
};
|
||||
format!("{:>6}{} {}{} {} {}{}{}", prefix, self.name, length, self.mode, self.seq, self.date, comment, parent)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Password {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
&& match (&self.parent, &other.parent) {
|
||||
(Some(s), Some(o)) => *s.lock() == *o.lock(),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
&& self.prefix == other.prefix
|
||||
&& self.length == other.length
|
||||
&& self.mode == other.mode
|
||||
&& self.seq == other.seq
|
||||
}
|
||||
}
|
||||
|
||||
fn camel_case(words: [&str; 6]) -> String {
|
||||
let mut camel_case_string = String::new();
|
||||
|
||||
@@ -128,34 +149,34 @@ fn camel_case(words: [&str; 6]) -> String {
|
||||
camel_case_string
|
||||
}
|
||||
|
||||
pub fn fix_password_recursion(entry: Rc<RefCell<Password>>) {
|
||||
pub fn fix_password_recursion(entry: PasswordRef) {
|
||||
let mut t1 = entry.clone();
|
||||
let mut t2 = entry;
|
||||
let mut t3: Option<Rc<RefCell<Password>>> = None;
|
||||
let mut t3: Option<PasswordRef> = None;
|
||||
loop {
|
||||
t2 = match &t2.clone().borrow().parent {
|
||||
t2 = match &t2.clone().lock().borrow().parent {
|
||||
Some(o) => o.clone(),
|
||||
None => break,
|
||||
};
|
||||
if std::ptr::eq(&*t1.borrow(), &*t2.borrow()) {
|
||||
if std::ptr::eq(&*t1.lock().borrow(), &*t2.lock().borrow()) {
|
||||
t3 = Some(t2.clone());
|
||||
break;
|
||||
}
|
||||
t1 = match &t1.clone().borrow().parent {
|
||||
t1 = match &t1.clone().lock().borrow().parent {
|
||||
Some(o) => o.clone(),
|
||||
None => break,
|
||||
};
|
||||
t2 = match &t2.clone().borrow().parent {
|
||||
t2 = match &t2.clone().lock().borrow().parent {
|
||||
Some(o) => o.clone(),
|
||||
None => break,
|
||||
};
|
||||
if std::ptr::eq(&*t1.borrow(), &*t2.borrow()) {
|
||||
if std::ptr::eq(&*t1.lock().borrow(), &*t2.lock().borrow()) {
|
||||
t3 = Some(t2.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
match t3 {
|
||||
Some(o) => o.borrow_mut().parent = None,
|
||||
Some(o) => o.lock().borrow_mut().parent = None,
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
@@ -166,7 +187,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn exec_recursion_test() {
|
||||
let p1 = Rc::new(RefCell::new(Password::new(
|
||||
let p1 = Password::from_password(Password::new(
|
||||
None,
|
||||
"p1".to_string(),
|
||||
None,
|
||||
@@ -174,13 +195,15 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 3),
|
||||
None,
|
||||
)));
|
||||
));
|
||||
|
||||
p1.borrow_mut().parent = Some(p1.clone());
|
||||
{
|
||||
p1.lock().borrow_mut().parent = Some(p1.clone());
|
||||
};
|
||||
fix_password_recursion(p1.clone());
|
||||
assert_eq!(p1.borrow().parent, None);
|
||||
assert_eq!(p1.lock().borrow().parent.is_none(), true);
|
||||
|
||||
let p2 = Rc::new(RefCell::new(Password::new(
|
||||
let p2 = Password::from_password(Password::new(
|
||||
None,
|
||||
"p2".to_string(),
|
||||
None,
|
||||
@@ -188,9 +211,9 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 3),
|
||||
None,
|
||||
)));
|
||||
p2.borrow_mut().parent = Some(p1.clone());
|
||||
let p3 = Rc::new(RefCell::new(Password::new(
|
||||
));
|
||||
p2.lock().borrow_mut().parent = Some(p1.clone());
|
||||
let p3 = Password::from_password(Password::new(
|
||||
None,
|
||||
"p3".to_string(),
|
||||
None,
|
||||
@@ -198,9 +221,9 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 3),
|
||||
None,
|
||||
)));
|
||||
p3.borrow_mut().parent = Some(p2.clone());
|
||||
let p4 = Rc::new(RefCell::new(Password::new(
|
||||
));
|
||||
p3.lock().borrow_mut().parent = Some(p2.clone());
|
||||
let p4 = Password::from_password(Password::new(
|
||||
None,
|
||||
"p4".to_string(),
|
||||
None,
|
||||
@@ -208,9 +231,9 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 3),
|
||||
None,
|
||||
)));
|
||||
p4.borrow_mut().parent = Some(p3.clone());
|
||||
let p5 = Rc::new(RefCell::new(Password::new(
|
||||
));
|
||||
p4.lock().borrow_mut().parent = Some(p3.clone());
|
||||
let p5 = Password::from_password(Password::new(
|
||||
None,
|
||||
"p5".to_string(),
|
||||
None,
|
||||
@@ -218,12 +241,12 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 3),
|
||||
None,
|
||||
)));
|
||||
p5.borrow_mut().parent = Some(p4.clone());
|
||||
));
|
||||
p5.lock().borrow_mut().parent = Some(p4.clone());
|
||||
|
||||
p1.borrow_mut().parent = Some(p3.clone());
|
||||
p1.lock().borrow_mut().parent = Some(p3.clone());
|
||||
fix_password_recursion(p5.clone());
|
||||
assert_eq!(p3.borrow().parent, None);
|
||||
assert_eq!(p3.lock().borrow().parent.is_none(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+89
-42
@@ -1,15 +1,13 @@
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::lk::LK;
|
||||
use crate::lk::LKRef;
|
||||
use crate::parser::command_parser;
|
||||
use crate::structs::{Command, LKErr, LKOut, HISTORY_FILE};
|
||||
use crate::utils::editor::{ Editor, password };
|
||||
use crate::utils::editor::{password, Editor};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LKRead {
|
||||
pub rl: Editor,
|
||||
pub prompt: String,
|
||||
pub state: Rc<RefCell<LK>>,
|
||||
pub state: LKRef,
|
||||
pub cmd: String,
|
||||
pub read_password: fn(String) -> std::io::Result<String>,
|
||||
}
|
||||
@@ -17,19 +15,19 @@ pub struct LKRead {
|
||||
#[derive(Debug)]
|
||||
pub struct LKEval<'a> {
|
||||
pub cmd: Command<'a>,
|
||||
pub state: Rc<RefCell<LK>>,
|
||||
pub state: LKRef,
|
||||
pub read_password: fn(String) -> std::io::Result<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug)]
|
||||
pub struct LKPrint {
|
||||
pub out: LKOut,
|
||||
pub quit: bool,
|
||||
pub state: Rc<RefCell<LK>>,
|
||||
pub state: LKRef,
|
||||
}
|
||||
|
||||
impl LKRead {
|
||||
pub fn new(rl: Editor, prompt: String, state: Rc<RefCell<LK>>) -> Self {
|
||||
pub fn new(rl: Editor, prompt: String, state: LKRef) -> Self {
|
||||
Self {
|
||||
rl,
|
||||
prompt,
|
||||
@@ -77,7 +75,7 @@ impl LKRead {
|
||||
}
|
||||
|
||||
impl<'a> LKEval<'a> {
|
||||
pub fn new(cmd: Command<'a>, state: Rc<RefCell<LK>>, read_password: fn(String) -> std::io::Result<String>) -> Self {
|
||||
pub fn new(cmd: Command<'a>, state: LKRef, read_password: fn(String) -> std::io::Result<String>) -> Self {
|
||||
Self {
|
||||
cmd,
|
||||
state,
|
||||
@@ -94,25 +92,33 @@ impl<'a> LKEval<'a> {
|
||||
out.e("Bye!".to_string());
|
||||
quit = true;
|
||||
}
|
||||
Command::Ls(filter) => self.cmd_ls(&out, filter.to_string(), |a,b| a.borrow().name.cmp(&b.borrow().name)),
|
||||
Command::Ld(filter) => self.cmd_ls(&out, filter.to_string(), |a,b| a.borrow().date.cmp(&b.borrow().date)),
|
||||
Command::Ls(filter) => {
|
||||
self.cmd_ls(&out, filter.to_string(), |a, b| a.lock().borrow().name.cmp(&b.lock().borrow().name))
|
||||
}
|
||||
Command::Ld(filter) => {
|
||||
self.cmd_ls(&out, filter.to_string(), |a, b| a.lock().borrow().date.cmp(&b.lock().borrow().date))
|
||||
}
|
||||
Command::Add(name) => self.cmd_add(&out, &name),
|
||||
Command::Leave(name) => self.cmd_leave(&out, &name),
|
||||
Command::Comment(name, comment) => self.cmd_comment(&out, &name, &comment),
|
||||
Command::Rm(name) => match self.get_password(name) {
|
||||
Some(pwd) => {
|
||||
self.state.borrow_mut().db.remove(&pwd.borrow().name);
|
||||
out.o(format!("removed {}", pwd.borrow().name));
|
||||
self.state.lock().borrow_mut().db.remove(&pwd.lock().borrow().name);
|
||||
out.o(format!("removed {}", pwd.lock().borrow().name));
|
||||
}
|
||||
None => out.e(format!("error: password {} not found", name)),
|
||||
},
|
||||
Command::Enc(name) => { self.cmd_enc(&out, name); }
|
||||
Command::Enc(name) => {
|
||||
self.cmd_enc(&out, name);
|
||||
}
|
||||
Command::Gen(num, name) => self.cmd_gen(&out, &num, &name),
|
||||
Command::PasteBuffer(command) => self.cmd_pb(&out, command),
|
||||
Command::Source(script) => { quit = self.cmd_source(&out, script); }
|
||||
Command::Source(script) => {
|
||||
quit = self.cmd_source(&out, script);
|
||||
}
|
||||
Command::Dump(script) => self.cmd_dump(&out, script),
|
||||
Command::Pass(name) => self.cmd_pass(&out, &name),
|
||||
Command::UnPass(name) => match self.state.borrow_mut().secrets.remove(name) {
|
||||
Command::UnPass(name) => match self.state.lock().borrow_mut().secrets.remove(name) {
|
||||
Some(_) => out.o(format!("Removed saved password for {}", name)),
|
||||
None => out.e(format!("error: saved password for {} not found", name)),
|
||||
},
|
||||
@@ -136,7 +142,7 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
|
||||
impl LKPrint {
|
||||
pub fn new(out: LKOut, quit: bool, state: Rc<RefCell<LK>>) -> Self {
|
||||
pub fn new(out: LKOut, quit: bool, state: LKRef) -> Self {
|
||||
Self { out, quit, state }
|
||||
}
|
||||
|
||||
@@ -147,16 +153,26 @@ impl LKPrint {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for LKPrint {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.out == other.out && self.quit == other.quit && *self.state.lock() == *other.state.lock()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::lk::LK;
|
||||
use crate::password::Password;
|
||||
use crate::structs::Mode;
|
||||
use std::collections::HashMap;
|
||||
use crate::utils::date::Date;
|
||||
use parking_lot::ReentrantMutex;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
impl<'a> LKEval<'a> {
|
||||
pub fn news(cmd: Command<'a>, state: Rc<RefCell<LK>>) -> Self {
|
||||
pub fn news(cmd: Command<'a>, state: LKRef) -> Self {
|
||||
Self {
|
||||
cmd,
|
||||
state,
|
||||
@@ -169,12 +185,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn exec_cmds_basic() {
|
||||
let lk = Rc::new(RefCell::new(LK::new()));
|
||||
let lk = Arc::new(ReentrantMutex::new(RefCell::new(LK::new())));
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Ls(".".to_string()), lk.clone()).eval(),
|
||||
LKPrint::new(LKOut::from_vecs(vec![], vec![]), false, lk.clone())
|
||||
);
|
||||
let pwd1 = Rc::new(RefCell::new(Password {
|
||||
let pwd1 = Password::from_password(Password {
|
||||
name: "t1".to_string(),
|
||||
prefix: None,
|
||||
length: None,
|
||||
@@ -183,12 +199,25 @@ mod tests {
|
||||
date: Date::new(2022, 12, 30),
|
||||
comment: Some("comment".to_string()),
|
||||
parent: None,
|
||||
}));
|
||||
assert_eq!(LKEval::news(Command::Add(pwd1.clone()), lk.clone()).eval().state.borrow().db, {
|
||||
let mut db = HashMap::new();
|
||||
db.insert(pwd1.borrow().name.to_string(), pwd1.clone());
|
||||
db
|
||||
});
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Add(pwd1.clone()), lk.clone())
|
||||
.eval()
|
||||
.state
|
||||
.lock()
|
||||
.borrow()
|
||||
.db
|
||||
.iter()
|
||||
.map(|x| (x.0.to_string(), x.1.lock().borrow().to_string()))
|
||||
.collect::<Vec<(String, String)>>(),
|
||||
{
|
||||
let mut db = HashMap::new();
|
||||
db.insert(pwd1.lock().borrow().name.to_string(), pwd1.clone());
|
||||
db.into_iter()
|
||||
.map(|x| (x.0.to_string(), x.1.lock().borrow().to_string()))
|
||||
.collect::<Vec<(String, String)>>()
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Ls(".".to_string()), lk.clone()).eval(),
|
||||
LKPrint::new(
|
||||
@@ -201,7 +230,7 @@ mod tests {
|
||||
LKEval::news(Command::Quit, lk.clone()).eval(),
|
||||
LKPrint::new(LKOut::from_vecs(vec![], vec!["Bye!".to_string()]), true, lk.clone())
|
||||
);
|
||||
let pwd2 = Rc::new(RefCell::new(Password {
|
||||
let pwd2 = Password::from_password(Password {
|
||||
name: "t2".to_string(),
|
||||
prefix: None,
|
||||
length: None,
|
||||
@@ -210,18 +239,32 @@ mod tests {
|
||||
date: Date::new(2022, 12, 31),
|
||||
comment: Some("bli blup".to_string()),
|
||||
parent: None,
|
||||
}));
|
||||
assert_eq!(LKEval::news(Command::Add(pwd2.clone()), lk.clone()).eval().state.borrow().db, {
|
||||
let mut db = HashMap::new();
|
||||
db.insert(pwd1.borrow().name.to_string(), pwd1.clone());
|
||||
db.insert(pwd2.borrow().name.to_string(), pwd2.clone());
|
||||
db
|
||||
});
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Add(pwd2.clone()), lk.clone())
|
||||
.eval()
|
||||
.state
|
||||
.lock()
|
||||
.borrow()
|
||||
.db
|
||||
.iter()
|
||||
.map(|x| (x.0.to_string(), x.1.lock().borrow().to_string()))
|
||||
.collect::<Vec<(String, String)>>(),
|
||||
{
|
||||
let mut db = HashMap::new();
|
||||
db.insert(pwd1.lock().borrow().name.to_string(), pwd1.clone());
|
||||
db.insert(pwd2.lock().borrow().name.to_string(), pwd2.clone());
|
||||
db.into_iter().map(|x| (x.0, x.1.lock().borrow().to_string())).collect::<Vec<(String, String)>>()
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Ls(".".to_string()), lk.clone()).eval(),
|
||||
LKPrint::new(
|
||||
LKOut::from_vecs(
|
||||
vec![" 1 t1 R 99 2022-12-30 comment".to_string(), " 2 t2 R 99 2022-12-31 bli blup".to_string()],
|
||||
vec![
|
||||
" 1 t1 R 99 2022-12-30 comment".to_string(),
|
||||
" 2 t2 R 99 2022-12-31 bli blup".to_string()
|
||||
],
|
||||
vec![]
|
||||
),
|
||||
false,
|
||||
@@ -244,8 +287,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn read_pwd_test() {
|
||||
let lk = Rc::new(RefCell::new(LK::new()));
|
||||
let t1 = Rc::new(RefCell::new(Password::new(
|
||||
let lk = Arc::new(ReentrantMutex::new(RefCell::new(LK::new())));
|
||||
let t1 = Password::from_password(Password::new(
|
||||
None,
|
||||
"t1".to_string(),
|
||||
None,
|
||||
@@ -253,8 +296,8 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 30),
|
||||
None,
|
||||
)));
|
||||
let t2 = Rc::new(RefCell::new(Password::new(
|
||||
));
|
||||
let t2 = Password::from_password(Password::new(
|
||||
None,
|
||||
"t2".to_string(),
|
||||
None,
|
||||
@@ -262,8 +305,8 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 30),
|
||||
None,
|
||||
)));
|
||||
let t3 = Rc::new(RefCell::new(Password::new(
|
||||
));
|
||||
let t3 = Password::from_password(Password::new(
|
||||
None,
|
||||
"t3".to_string(),
|
||||
None,
|
||||
@@ -271,19 +314,23 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 12, 30),
|
||||
None,
|
||||
)));
|
||||
));
|
||||
println!("POINT 1");
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Add(t1.clone()), lk.clone()).eval(),
|
||||
LKPrint::new(LKOut::from_vecs(vec![], vec![]), false, lk.clone())
|
||||
);
|
||||
println!("POINT 2");
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Add(t2.clone()), lk.clone()).eval(),
|
||||
LKPrint::new(LKOut::from_vecs(vec![], vec![]), false, lk.clone())
|
||||
);
|
||||
println!("POINT 3");
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Add(t3.clone()), lk.clone()).eval(),
|
||||
LKPrint::new(LKOut::from_vecs(vec![], vec![]), false, lk.clone())
|
||||
);
|
||||
println!("POINT 4");
|
||||
assert_eq!(
|
||||
LKEval::news(Command::Mv("t3".to_string(), "t2".to_string()), lk.clone()).eval(),
|
||||
LKPrint::new(LKOut::from_vecs(vec![], vec![]), false, lk.clone())
|
||||
|
||||
+81
-36
@@ -1,13 +1,16 @@
|
||||
use crate::password::{Comment, Name, PasswordRef};
|
||||
use parking_lot::Mutex;
|
||||
use parking_lot::ReentrantMutex;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::lk::LK;
|
||||
use crate::parser::command_parser;
|
||||
use crate::repl::{LKEval, LKRead};
|
||||
use crate::utils::editor::{password, Editor};
|
||||
use crate::utils::home;
|
||||
use crate::utils::editor::{ Editor, password };
|
||||
|
||||
lazy_static! {
|
||||
pub static ref HISTORY_FILE: Box<Path> = {
|
||||
@@ -54,7 +57,7 @@ pub enum LKErr<'a> {
|
||||
ParseError(peg::error::ParseError<peg::str::LineCol>),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub enum Command<'a> {
|
||||
Add(PasswordRef),
|
||||
Leave(Name),
|
||||
@@ -78,6 +81,34 @@ pub enum Command<'a> {
|
||||
Quit,
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for Command<'a> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Command::Add(s), Command::Add(o)) => *s.lock() == *o.lock(),
|
||||
(Command::Leave(s), Command::Leave(o)) => s == o,
|
||||
(Command::Ls(s), Command::Ls(o)) => s == o,
|
||||
(Command::Ld(s), Command::Ld(o)) => s == o,
|
||||
(Command::Mv(a, b), Command::Mv(x, y)) => a == x && b == y,
|
||||
(Command::Rm(s), Command::Rm(o)) => s == o,
|
||||
(Command::Enc(s), Command::Enc(o)) => s == o,
|
||||
(Command::Gen(a, b), Command::Gen(x, y)) => a == x && *b.lock() == *y.lock(),
|
||||
(Command::Pass(s), Command::Pass(o)) => s == o,
|
||||
(Command::UnPass(s), Command::UnPass(o)) => s == o,
|
||||
(Command::Correct(s), Command::Correct(o)) => s == o,
|
||||
(Command::Uncorrect(s), Command::Uncorrect(o)) => s == o,
|
||||
(Command::PasteBuffer(s), Command::PasteBuffer(o)) => s == o,
|
||||
(Command::Source(s), Command::Source(o)) => s == o,
|
||||
(Command::Dump(s), Command::Dump(o)) => s == o,
|
||||
(Command::Comment(a, b), Command::Comment(x, y)) => a == x && b == y,
|
||||
(Command::Error(s), Command::Error(o)) => s == o,
|
||||
(Command::Noop, Command::Noop) => true,
|
||||
(Command::Help, Command::Help) => true,
|
||||
(Command::Quit, Command::Quit) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Mode {
|
||||
Regular,
|
||||
@@ -114,21 +145,21 @@ impl std::fmt::Display for Mode {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub struct LKOut {
|
||||
pub out: Option<Rc<RefCell<Vec<String>>>>,
|
||||
pub err: Option<Rc<RefCell<Vec<String>>>>,
|
||||
pub out: Option<Arc<Mutex<Vec<String>>>>,
|
||||
pub err: Option<Arc<Mutex<Vec<String>>>>,
|
||||
}
|
||||
|
||||
impl LKOut {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
out: Some(Rc::new(RefCell::new(vec![]))),
|
||||
err: Some(Rc::new(RefCell::new(vec![]))),
|
||||
out: Some(Arc::new(Mutex::new(vec![]))),
|
||||
err: Some(Arc::new(Mutex::new(vec![]))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_lkout(out: Option<Rc<RefCell<Vec<String>>>>, err: Option<Rc<RefCell<Vec<String>>>>) -> Self {
|
||||
pub fn from_lkout(out: Option<Arc<Mutex<Vec<String>>>>, err: Option<Arc<Mutex<Vec<String>>>>) -> Self {
|
||||
let o = match out {
|
||||
Some(v) => Some(v.clone()),
|
||||
None => None,
|
||||
@@ -143,8 +174,8 @@ impl LKOut {
|
||||
#[allow(dead_code)]
|
||||
pub fn from_vecs(out: Vec<String>, err: Vec<String>) -> Self {
|
||||
Self {
|
||||
out: Some(Rc::new(RefCell::new(out))),
|
||||
err: Some(Rc::new(RefCell::new(err))),
|
||||
out: Some(Arc::new(Mutex::new(out))),
|
||||
err: Some(Arc::new(Mutex::new(err))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +183,7 @@ impl LKOut {
|
||||
if !self.out.is_some() {
|
||||
return;
|
||||
}
|
||||
for line in self.out.as_ref().unwrap().borrow().iter() {
|
||||
for line in self.out.as_ref().unwrap().lock().iter() {
|
||||
out.o(line.to_string())
|
||||
}
|
||||
}
|
||||
@@ -161,7 +192,7 @@ impl LKOut {
|
||||
if !self.err.is_some() {
|
||||
return;
|
||||
}
|
||||
for line in self.err.as_ref().unwrap().borrow().iter() {
|
||||
for line in self.err.as_ref().unwrap().lock().iter() {
|
||||
out.e(line.to_string())
|
||||
}
|
||||
}
|
||||
@@ -170,7 +201,7 @@ impl LKOut {
|
||||
if !self.out.is_some() {
|
||||
return;
|
||||
}
|
||||
for line in self.out.as_ref().unwrap().borrow().iter() {
|
||||
for line in self.out.as_ref().unwrap().lock().iter() {
|
||||
println!("{}", line);
|
||||
}
|
||||
}
|
||||
@@ -179,7 +210,7 @@ impl LKOut {
|
||||
if !self.err.is_some() {
|
||||
return;
|
||||
}
|
||||
for line in self.err.as_ref().unwrap().borrow().iter() {
|
||||
for line in self.err.as_ref().unwrap().lock().iter() {
|
||||
eprintln!("{}", line);
|
||||
}
|
||||
}
|
||||
@@ -191,7 +222,7 @@ impl LKOut {
|
||||
|
||||
pub fn data(&self) -> String {
|
||||
if self.out.is_some() {
|
||||
self.out.as_ref().unwrap().borrow().join("\n")
|
||||
self.out.as_ref().unwrap().lock().join("\n")
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
@@ -202,16 +233,30 @@ impl LKOut {
|
||||
}
|
||||
pub fn o(&self, line: String) {
|
||||
if self.out.is_some() {
|
||||
self.out.as_ref().unwrap().borrow_mut().push(line);
|
||||
self.out.as_ref().unwrap().lock().push(line);
|
||||
}
|
||||
}
|
||||
pub fn e(&self, line: String) {
|
||||
if self.err.is_some() {
|
||||
self.err.as_ref().unwrap().borrow_mut().push(line);
|
||||
self.err.as_ref().unwrap().lock().push(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for LKOut {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
(match (&self.out, &other.out) {
|
||||
(Some(a), Some(b)) => *a.lock() == *b.lock(),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
} && match (&self.err, &other.err) {
|
||||
(Some(a), Some(b)) => *a.lock() == *b.lock(),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Radix {
|
||||
x: i32,
|
||||
radix: u32,
|
||||
@@ -263,13 +308,15 @@ impl fmt::Display for Radix {
|
||||
}
|
||||
|
||||
pub fn init() -> Option<LKRead> {
|
||||
let lk = Rc::new(RefCell::new(LK::new()));
|
||||
let lk = Arc::new(ReentrantMutex::new(RefCell::new(LK::new())));
|
||||
|
||||
match std::fs::read_to_string(INIT_FILE.to_str().unwrap()) {
|
||||
Ok(script) => match command_parser::script(&script) {
|
||||
Ok(cmd_list) => {
|
||||
for cmd in cmd_list {
|
||||
if !LKEval::new(cmd, lk.clone(), password).eval().print() { return None; }
|
||||
if !LKEval::new(cmd, lk.clone(), password).eval().print() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -349,9 +396,9 @@ mod tests {
|
||||
|
||||
let lkread = init().unwrap();
|
||||
assert_eq!(lkread.prompt, "test> ");
|
||||
assert_eq!(lkread.state.borrow().db.contains_key("t1"), true);
|
||||
assert_eq!(lkread.state.lock().borrow().db.contains_key("t1"), true);
|
||||
|
||||
let t1 = Rc::new(RefCell::new(Password::new(
|
||||
let t1 = Password::from_password(Password::new(
|
||||
None,
|
||||
"t1".to_string(),
|
||||
None,
|
||||
@@ -359,8 +406,8 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 10, 10),
|
||||
None,
|
||||
)));
|
||||
let t2 = Rc::new(RefCell::new(Password::new(
|
||||
));
|
||||
let t2 = Password::from_password(Password::new(
|
||||
None,
|
||||
"t2".to_string(),
|
||||
None,
|
||||
@@ -368,9 +415,9 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 10, 10),
|
||||
Some("test".to_string()),
|
||||
)));
|
||||
t2.borrow_mut().parent = Some(t1.clone());
|
||||
let t3 = Rc::new(RefCell::new(Password::new(
|
||||
));
|
||||
t2.lock().borrow_mut().parent = Some(t1.clone());
|
||||
let t3 = Password::from_password(Password::new(
|
||||
None,
|
||||
"t3".to_string(),
|
||||
None,
|
||||
@@ -378,15 +425,13 @@ mod tests {
|
||||
99,
|
||||
Date::new(2022, 10, 10),
|
||||
Some("aoeu".to_string()),
|
||||
)));
|
||||
t3.borrow_mut().parent = Some(t2.clone());
|
||||
assert_eq!(*lkread.state.borrow().db.get("t1").unwrap().borrow(), *t1.borrow());
|
||||
assert_eq!(*lkread.state.borrow().db.get("t2").unwrap().borrow(), *t2.borrow());
|
||||
assert_eq!(*lkread.state.borrow().db.get("t3").unwrap().borrow(), *t3.borrow());
|
||||
));
|
||||
t3.lock().borrow_mut().parent = Some(t2.clone());
|
||||
assert_eq!(*lkread.state.lock().borrow().db.get("t1").unwrap().lock(), *t1.lock());
|
||||
assert_eq!(*lkread.state.lock().borrow().db.get("t2").unwrap().lock(), *t2.lock());
|
||||
assert_eq!(*lkread.state.lock().borrow().db.get("t3").unwrap().lock(), *t3.lock());
|
||||
|
||||
LKEval::new(command_parser::cmd("save").unwrap(), lkread.state.clone(), password)
|
||||
.eval()
|
||||
.print();
|
||||
LKEval::new(command_parser::cmd("save").unwrap(), lkread.state.clone(), password).eval().print();
|
||||
assert_eq!(
|
||||
std::fs::read_to_string("test_dump").expect("read"),
|
||||
"add t1 R 99 2022-10-10\nadd t2 R 99 2022-10-10 test ^t1\nadd t3 R 99 2022-10-10 aoeu ^t2\n".to_string()
|
||||
@@ -412,7 +457,7 @@ mod tests {
|
||||
]
|
||||
)
|
||||
);
|
||||
lkread.state.borrow_mut().secrets.clear();
|
||||
lkread.state.lock().borrow_mut().secrets.clear();
|
||||
let pr = LKEval::new(command_parser::cmd("pb enc t3").unwrap(), lkread.state.clone(), |v| {
|
||||
if v == "/" {
|
||||
Ok("a".to_string())
|
||||
|
||||
+10
-4
@@ -11,12 +11,14 @@ pub mod date {
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
pub struct Date {
|
||||
date: NaiveDate
|
||||
date: NaiveDate,
|
||||
}
|
||||
|
||||
impl Date {
|
||||
pub fn new(year: i32, month: u32, day: u32) -> Self {
|
||||
Self { date: NaiveDate::from_ymd_opt(year, month, day).unwrap() }
|
||||
Self {
|
||||
date: NaiveDate::from_ymd_opt(year, month, day).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_new(year: i32, month: u32, day: u32) -> Result<Self, &'static str> {
|
||||
@@ -27,7 +29,9 @@ pub mod date {
|
||||
}
|
||||
|
||||
pub fn now() -> Self {
|
||||
Self { date: Local::now().naive_local().date() }
|
||||
Self {
|
||||
date: Local::now().naive_local().date(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmp(&self, other: &Self) -> core::cmp::Ordering {
|
||||
@@ -95,7 +99,9 @@ pub mod editor {
|
||||
|
||||
impl Editor {
|
||||
pub fn new() -> Self {
|
||||
Self { editor: rustyline::Editor::<()>::new().unwrap() }
|
||||
Self {
|
||||
editor: rustyline::Editor::<()>::new().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_history(&mut self) {
|
||||
|
||||
Reference in New Issue
Block a user