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