Split project into three workspaces: hel (the library), helcli (the tool) and helwasm (the wasm code). Move wasm incompatible code to extra modules in utils.rs to be implementable separately for wasm.
This commit is contained in:
+2
-25
@@ -1,25 +1,2 @@
|
|||||||
[package]
|
[workspace]
|
||||||
name = "hel"
|
members = ["hel", "helcli", "helwasm"]
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["ok2"]
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
chrono = "0.4.23"
|
|
||||||
peg = "0.8.1"
|
|
||||||
anyhow = "1.0.66"
|
|
||||||
lazy_static = "1.4.0"
|
|
||||||
regex = "1.6.0"
|
|
||||||
rustyline = "10.0.0"
|
|
||||||
thiserror = "1.0.37"
|
|
||||||
anyerror = "0.1.7"
|
|
||||||
home = "0.5.4"
|
|
||||||
sha1 = "0.10.5"
|
|
||||||
base64 = "0.20.0"
|
|
||||||
rpassword = "7.2.0"
|
|
||||||
shlex = "1.1.0"
|
|
||||||
shellexpand = "3.0.0"
|
|
||||||
scopeguard = "1.1.0"
|
|
||||||
rand = "0.8.5"
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
[package]
|
||||||
|
name = "hel"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ok2"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "hel"
|
||||||
|
crate-type = ["lib"]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
peg = "0.8.1"
|
||||||
|
anyhow = "1.0.66"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
regex = "1.6.0"
|
||||||
|
thiserror = "1.0.37"
|
||||||
|
anyerror = "0.1.7"
|
||||||
|
sha1 = "0.10.5"
|
||||||
|
base64 = "0.20.0"
|
||||||
|
rpassword = "7.2.0"
|
||||||
|
shlex = "1.1.0"
|
||||||
|
shellexpand = "3.0.0"
|
||||||
|
scopeguard = "1.1.0"
|
||||||
|
|
||||||
|
[target.'cfg(not(wasm))'.dependencies]
|
||||||
|
chrono = "0.4.23"
|
||||||
|
rand = "0.8.5"
|
||||||
|
home = "0.5.4"
|
||||||
|
rustyline = "10.0.0"
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
use rand::{thread_rng, Rng};
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rpassword::prompt_password;
|
use rpassword::prompt_password;
|
||||||
use sha1::{Digest, Sha1};
|
use sha1::{Digest, Sha1};
|
||||||
@@ -13,7 +12,7 @@ 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};
|
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> {
|
||||||
@@ -429,7 +428,6 @@ impl<'a> LKEval<'a> {
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref RE: Regex = Regex::new(r"^.+?(G+|X+)$").unwrap();
|
static ref RE: Regex = Regex::new(r"^.+?(G+|X+)$").unwrap();
|
||||||
}
|
}
|
||||||
let mut rng = thread_rng();
|
|
||||||
let num: usize = (*num).try_into().unwrap();
|
let num: usize = (*num).try_into().unwrap();
|
||||||
let pwd = name.borrow();
|
let pwd = name.borrow();
|
||||||
let mut genpwds: Vec<PasswordRef> = Vec::new();
|
let mut genpwds: Vec<PasswordRef> = Vec::new();
|
||||||
@@ -445,7 +443,7 @@ impl<'a> LKEval<'a> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let name = pwd.name.trim_end_matches('X');
|
let name = pwd.name.trim_end_matches('X');
|
||||||
let num = rng.gen_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(&pwd);
|
||||||
npwd.borrow_mut().name = format!("{}{}", name, num).to_string();
|
npwd.borrow_mut().name = format!("{}{}", name, num).to_string();
|
||||||
genpwds.push(npwd);
|
genpwds.push(npwd);
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
#[macro_use(defer)]
|
||||||
|
extern crate scopeguard;
|
||||||
|
|
||||||
|
pub mod commands;
|
||||||
|
pub mod lk;
|
||||||
|
pub mod parser;
|
||||||
|
pub mod password;
|
||||||
|
pub mod repl;
|
||||||
|
pub mod skey;
|
||||||
|
pub mod structs;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
@@ -2,8 +2,7 @@ extern crate peg;
|
|||||||
|
|
||||||
use crate::password::Password;
|
use crate::password::Password;
|
||||||
use crate::structs::{Command, LKErr, Mode};
|
use crate::structs::{Command, LKErr, Mode};
|
||||||
use chrono::naive::NaiveDate;
|
use crate::utils::date::Date;
|
||||||
use chrono::Local;
|
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
peg::parser! {
|
peg::parser! {
|
||||||
@@ -42,21 +41,21 @@ peg::parser! {
|
|||||||
rule sname() -> Password = &(word() _ num()? mode() _ date()) pn:word() _ pl:num()? pm:mode() _ pd:date() pc:comment()?
|
rule sname() -> Password = &(word() _ num()? mode() _ date()) pn:word() _ pl:num()? pm:mode() _ pd:date() pc:comment()?
|
||||||
{ Password::new(None, pn, pl, pm, 99, pd, pc) }
|
{ Password::new(None, pn, pl, pm, 99, pd, pc) }
|
||||||
rule nname() -> Password = &(word() _ num()? mode()) pn:word() _ pl:num()? pm:mode()
|
rule nname() -> Password = &(word() _ num()? mode()) pn:word() _ pl:num()? pm:mode()
|
||||||
{ Password::new(None, pn, pl, pm, 99, Local::now().naive_local().date(), None) }
|
{ Password::new(None, pn, pl, pm, 99, Date::now(), None) }
|
||||||
rule qname() -> Password = &(word()) pn:word()
|
rule qname() -> Password = &(word()) pn:word()
|
||||||
{ Password::new(None, pn, None, Mode::NoSpaceCamel, 99, Local::now().naive_local().date(), None) }
|
{ Password::new(None, pn, None, Mode::NoSpaceCamel, 99, Date::now(), None) }
|
||||||
pub rule name() -> Password = name:(jname() / pname() / mname() / sname() / nname() / qname())? {?
|
pub rule name() -> Password = name:(jname() / pname() / mname() / sname() / nname() / qname())? {?
|
||||||
match name { Some(n) => Ok(n), None => Err("failed to parse password description") }
|
match name { Some(n) => Ok(n), None => Err("failed to parse password description") }
|
||||||
}
|
}
|
||||||
|
|
||||||
rule ndate() -> NaiveDate = y:$("-"? ['0'..='9']*<1,4>) "-" m:$(['0'..='9']*<1,2>) "-" d:$(['0'..='9']*<1,2>) {?
|
rule ndate() -> Date = y:$("-"? ['0'..='9']*<1,4>) "-" m:$(['0'..='9']*<1,2>) "-" d:$(['0'..='9']*<1,2>) {?
|
||||||
let year: i32 = match y.parse() { Ok(n) => n, Err(_) => return Err("year") };
|
let year: i32 = match y.parse() { Ok(n) => n, Err(_) => return Err("year") };
|
||||||
let month: u32 = match m.parse() { Ok(n) => n, Err(_) => return Err("month") };
|
let month: u32 = match m.parse() { Ok(n) => n, Err(_) => return Err("month") };
|
||||||
let day: u32 = match d.parse() { Ok(n) => n, Err(_) => return Err("day") };
|
let day: u32 = match d.parse() { Ok(n) => n, Err(_) => return Err("day") };
|
||||||
NaiveDate::from_ymd_opt(year, month, day).ok_or("date")
|
Date::try_new(year, month, day)
|
||||||
}
|
}
|
||||||
rule cdate() -> NaiveDate = "now" { Local::now().naive_local().date() }
|
rule cdate() -> Date = "now" { Date::now() }
|
||||||
rule date() -> NaiveDate = d:(ndate() / cdate()) { d }
|
rule date() -> Date = d:(ndate() / cdate()) { d }
|
||||||
rule umode() -> Mode = ("U" / "u") m:$("R" / "r" / "N" / "n" / "H" / "h" / "B" / "b") {?
|
rule umode() -> Mode = ("U" / "u") m:$("R" / "r" / "N" / "n" / "H" / "h" / "B" / "b") {?
|
||||||
match m.to_uppercase().as_str() {
|
match m.to_uppercase().as_str() {
|
||||||
"R" => Ok(Mode::RegularUpcase),
|
"R" => Ok(Mode::RegularUpcase),
|
||||||
@@ -126,7 +125,7 @@ add t3 C 99 2022-12-14"###
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Add(Rc::new(RefCell::new(Password {
|
Command::Add(Rc::new(RefCell::new(Password {
|
||||||
@@ -136,7 +135,7 @@ add t3 C 99 2022-12-14"###
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Add(Rc::new(RefCell::new(Password {
|
Command::Add(Rc::new(RefCell::new(Password {
|
||||||
@@ -146,7 +145,7 @@ add t3 C 99 2022-12-14"###
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
})))
|
})))
|
||||||
])
|
])
|
||||||
@@ -166,7 +165,7 @@ add t3 C 99 2022-12-14
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Add(Rc::new(RefCell::new(Password {
|
Command::Add(Rc::new(RefCell::new(Password {
|
||||||
@@ -176,7 +175,7 @@ add t3 C 99 2022-12-14
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Add(Rc::new(RefCell::new(Password {
|
Command::Add(Rc::new(RefCell::new(Password {
|
||||||
@@ -186,7 +185,7 @@ add t3 C 99 2022-12-14
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Noop
|
Command::Noop
|
||||||
@@ -208,7 +207,7 @@ add t3 C 99 2022-12-14
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Add(Rc::new(RefCell::new(Password {
|
Command::Add(Rc::new(RefCell::new(Password {
|
||||||
@@ -218,7 +217,7 @@ add t3 C 99 2022-12-14
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Add(Rc::new(RefCell::new(Password {
|
Command::Add(Rc::new(RefCell::new(Password {
|
||||||
@@ -228,7 +227,7 @@ add t3 C 99 2022-12-14
|
|||||||
length: None,
|
length: None,
|
||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2022, 12, 14).unwrap(),
|
date: Date::new(2022, 12, 14),
|
||||||
comment: None
|
comment: None
|
||||||
}))),
|
}))),
|
||||||
Command::Noop,
|
Command::Noop,
|
||||||
@@ -248,7 +247,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::Regular,
|
mode: Mode::Regular,
|
||||||
length: None,
|
length: None,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -261,7 +260,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::RegularUpcase,
|
mode: Mode::RegularUpcase,
|
||||||
length: None,
|
length: None,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -274,7 +273,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::RegularUpcase,
|
mode: Mode::RegularUpcase,
|
||||||
length: None,
|
length: None,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: None
|
comment: None
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -287,7 +286,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::Regular,
|
mode: Mode::Regular,
|
||||||
length: None,
|
length: None,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -300,7 +299,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::NoSpace,
|
mode: Mode::NoSpace,
|
||||||
length: None,
|
length: None,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -313,7 +312,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::NoSpaceUpcase,
|
mode: Mode::NoSpaceUpcase,
|
||||||
length: None,
|
length: None,
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
comment: Some("xx.ableton@domain.info https://www.ableton.com".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -326,7 +325,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::Regular,
|
mode: Mode::Regular,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -339,7 +338,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::RegularUpcase,
|
mode: Mode::RegularUpcase,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -352,7 +351,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::HexUpcase,
|
mode: Mode::HexUpcase,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -365,7 +364,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::Base64Upcase,
|
mode: Mode::Base64Upcase,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -378,7 +377,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::Decimal,
|
mode: Mode::Decimal,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -391,7 +390,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::Decimal,
|
mode: Mode::Decimal,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 98,
|
seq: 98,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -404,7 +403,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::NoSpaceCamel,
|
mode: Mode::NoSpaceCamel,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 98,
|
seq: 98,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -417,7 +416,7 @@ add t3 C 99 2022-12-14
|
|||||||
mode: Mode::Decimal,
|
mode: Mode::Decimal,
|
||||||
length: Some(20),
|
length: Some(20),
|
||||||
seq: 99,
|
seq: 99,
|
||||||
date: NaiveDate::from_ymd_opt(2020, 12, 09).unwrap(),
|
date: Date::new(2020, 12, 09),
|
||||||
comment: Some("a b c".to_string())
|
comment: Some("a b c".to_string())
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::skey::SKey;
|
use crate::skey::SKey;
|
||||||
use crate::structs::Mode;
|
use crate::structs::Mode;
|
||||||
use chrono::naive::NaiveDate;
|
use crate::utils::date::Date;
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
pub type Name = String;
|
pub type Name = String;
|
||||||
@@ -10,7 +10,6 @@ pub type PasswordRef = Rc<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;
|
||||||
pub type Date = NaiveDate;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct Password {
|
pub struct Password {
|
||||||
@@ -173,7 +172,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
Mode::Regular,
|
Mode::Regular,
|
||||||
99,
|
99,
|
||||||
NaiveDate::from_ymd_opt(2022, 12, 3).unwrap(),
|
Date::new(2022, 12, 3),
|
||||||
None,
|
None,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
@@ -187,7 +186,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
Mode::Regular,
|
Mode::Regular,
|
||||||
99,
|
99,
|
||||||
NaiveDate::from_ymd_opt(2022, 12, 3).unwrap(),
|
Date::new(2022, 12, 3),
|
||||||
None,
|
None,
|
||||||
)));
|
)));
|
||||||
p2.borrow_mut().parent = Some(p1.clone());
|
p2.borrow_mut().parent = Some(p1.clone());
|
||||||
@@ -197,7 +196,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
Mode::Regular,
|
Mode::Regular,
|
||||||
99,
|
99,
|
||||||
NaiveDate::from_ymd_opt(2022, 12, 3).unwrap(),
|
Date::new(2022, 12, 3),
|
||||||
None,
|
None,
|
||||||
)));
|
)));
|
||||||
p3.borrow_mut().parent = Some(p2.clone());
|
p3.borrow_mut().parent = Some(p2.clone());
|
||||||
@@ -207,7 +206,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
Mode::Regular,
|
Mode::Regular,
|
||||||
99,
|
99,
|
||||||
NaiveDate::from_ymd_opt(2022, 12, 3).unwrap(),
|
Date::new(2022, 12, 3),
|
||||||
None,
|
None,
|
||||||
)));
|
)));
|
||||||
p4.borrow_mut().parent = Some(p3.clone());
|
p4.borrow_mut().parent = Some(p3.clone());
|
||||||
@@ -217,7 +216,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
Mode::Regular,
|
Mode::Regular,
|
||||||
99,
|
99,
|
||||||
NaiveDate::from_ymd_opt(2022, 12, 3).unwrap(),
|
Date::new(2022, 12, 3),
|
||||||
None,
|
None,
|
||||||
)));
|
)));
|
||||||
p5.borrow_mut().parent = Some(p4.clone());
|
p5.borrow_mut().parent = Some(p4.clone());
|
||||||
@@ -230,7 +229,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn exec_encode_test() {
|
fn exec_encode_test() {
|
||||||
let sec = "my secret";
|
let sec = "my secret";
|
||||||
let dat = NaiveDate::from_ymd_opt(2022, 12, 3).unwrap();
|
let dat = Date::new(2022, 12, 3);
|
||||||
|
|
||||||
let mut pwd = Password::new(None, "test1".to_string(), None, Mode::Regular, 99, dat, None);
|
let mut pwd = Password::new(None, "test1".to_string(), None, Mode::Regular, 99, dat, None);
|
||||||
assert_eq!(pwd.encode(sec), "ross beau week held yoga anti");
|
assert_eq!(pwd.encode(sec), "ross beau week held yoga anti");
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
use rpassword::prompt_password;
|
use rpassword::prompt_password;
|
||||||
use rustyline::error::ReadlineError;
|
|
||||||
use rustyline::Editor;
|
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use crate::lk::LK;
|
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;
|
||||||
|
|
||||||
#[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: Rc<RefCell<LK>>,
|
||||||
pub cmd: String,
|
pub cmd: String,
|
||||||
@@ -31,7 +30,7 @@ pub struct LKPrint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LKRead {
|
impl LKRead {
|
||||||
pub fn new(rl: Editor<()>, prompt: String, state: Rc<RefCell<LK>>) -> Self {
|
pub fn new(rl: Editor, prompt: String, state: Rc<RefCell<LK>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
rl,
|
rl,
|
||||||
prompt,
|
prompt,
|
||||||
@@ -53,7 +52,7 @@ impl LKRead {
|
|||||||
}
|
}
|
||||||
self.cmd = match self.rl.readline(&*self.prompt) {
|
self.cmd = match self.rl.readline(&*self.prompt) {
|
||||||
Ok(str) => str,
|
Ok(str) => str,
|
||||||
Err(ReadlineError::Eof | ReadlineError::Interrupted) => "quit".to_string(),
|
Err(LKErr::EOF) => "quit".to_string(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return LKEval::new(
|
return LKEval::new(
|
||||||
Command::Error(LKErr::ReadError(err.to_string())),
|
Command::Error(LKErr::ReadError(err.to_string())),
|
||||||
@@ -128,6 +127,7 @@ impl<'a> LKEval<'a> {
|
|||||||
Command::Error(error) => match error {
|
Command::Error(error) => match error {
|
||||||
LKErr::ParseError(e) => out.e(e.to_string()),
|
LKErr::ParseError(e) => out.e(e.to_string()),
|
||||||
LKErr::ReadError(e) => out.e(e.to_string()),
|
LKErr::ReadError(e) => out.e(e.to_string()),
|
||||||
|
LKErr::EOF => out.e("error: end of file".to_string()),
|
||||||
LKErr::Error(e) => out.e(format!("error: {}", e.to_string())),
|
LKErr::Error(e) => out.e(format!("error: {}", e.to_string())),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
use crate::password::{Comment, Name, PasswordRef};
|
use crate::password::{Comment, Name, PasswordRef};
|
||||||
use home::home_dir;
|
|
||||||
use rpassword::prompt_password;
|
use rpassword::prompt_password;
|
||||||
use rustyline::Editor;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
@@ -9,12 +7,14 @@ use std::{cell::RefCell, rc::Rc};
|
|||||||
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::home;
|
||||||
|
use crate::utils::editor::Editor;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref HISTORY_FILE: Box<Path> = {
|
pub static ref HISTORY_FILE: Box<Path> = {
|
||||||
match std::env::var("HEL_HISTORY") {
|
match std::env::var("HEL_HISTORY") {
|
||||||
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
||||||
_ => home_dir().unwrap().join(".hel_history").into_boxed_path(),
|
_ => home::dir().join(".hel_history").into_boxed_path(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
pub static ref PROMPT_SETTING: String = {
|
pub static ref PROMPT_SETTING: String = {
|
||||||
@@ -26,19 +26,19 @@ lazy_static! {
|
|||||||
pub static ref INIT_FILE: Box<Path> = {
|
pub static ref INIT_FILE: Box<Path> = {
|
||||||
match std::env::var("HEL_INIT") {
|
match std::env::var("HEL_INIT") {
|
||||||
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
||||||
_ => home_dir().unwrap().join(".helrc").into_boxed_path(),
|
_ => home::dir().join(".helrc").into_boxed_path(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
pub static ref CORRECT_FILE: Box<Path> = {
|
pub static ref CORRECT_FILE: Box<Path> = {
|
||||||
match std::env::var("HEL_CORRECT") {
|
match std::env::var("HEL_CORRECT") {
|
||||||
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
||||||
_ => home_dir().unwrap().join(".hel_correct").into_boxed_path(),
|
_ => home::dir().join(".hel_correct").into_boxed_path(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
pub static ref DUMP_FILE: Box<Path> = {
|
pub static ref DUMP_FILE: Box<Path> = {
|
||||||
match std::env::var("HEL_DUMP") {
|
match std::env::var("HEL_DUMP") {
|
||||||
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
Ok(v) => Path::new(shellexpand::full(&v).unwrap().into_owned().as_str()).to_path_buf().into_boxed_path(),
|
||||||
_ => home_dir().unwrap().join(".hel_dump").into_boxed_path(),
|
_ => home::dir().join(".hel_dump").into_boxed_path(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -47,6 +47,8 @@ lazy_static! {
|
|||||||
pub enum LKErr<'a> {
|
pub enum LKErr<'a> {
|
||||||
#[error("Error: {0}")]
|
#[error("Error: {0}")]
|
||||||
Error(&'a str),
|
Error(&'a str),
|
||||||
|
#[error("Error: end of file")]
|
||||||
|
EOF,
|
||||||
#[error("Failed to read the line: {0}")]
|
#[error("Failed to read the line: {0}")]
|
||||||
ReadError(String),
|
ReadError(String),
|
||||||
#[error("Failed to parse: {0}")]
|
#[error("Failed to parse: {0}")]
|
||||||
@@ -288,7 +290,7 @@ pub fn init() -> Option<LKRead> {
|
|||||||
.print();
|
.print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(LKRead::new(Editor::<()>::new().unwrap(), PROMPT_SETTING.to_string(), lk.clone()))
|
Some(LKRead::new(Editor::new(), PROMPT_SETTING.to_string(), lk.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
use shlex::split;
|
||||||
|
use std::env;
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::io;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
|
#[cfg(not(wasm))]
|
||||||
|
pub mod date {
|
||||||
|
use chrono::naive::NaiveDate;
|
||||||
|
use chrono::Local;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
pub struct Date {
|
||||||
|
date: NaiveDate
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Date {
|
||||||
|
pub fn new(year: i32, month: u32, day: u32) -> Self {
|
||||||
|
Self { date: NaiveDate::from_ymd_opt(year, month, day).unwrap() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn try_new(year: i32, month: u32, day: u32) -> Result<Self, &'static str> {
|
||||||
|
match NaiveDate::from_ymd_opt(year, month, day) {
|
||||||
|
Some(d) => Ok(Self { date: d }),
|
||||||
|
None => Err("error: failed to parse the date"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn now() -> Self {
|
||||||
|
Self { date: Local::now().naive_local().date() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cmp(&self, other: &Self) -> core::cmp::Ordering {
|
||||||
|
self.date.cmp(&other.date)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Date {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.date.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(wasm))]
|
||||||
|
pub mod rnd {
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
|
pub fn range(start: u32, end: u32) -> u32 {
|
||||||
|
thread_rng().gen_range(start..end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub mod home {
|
||||||
|
use home::home_dir;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
pub fn dir() -> PathBuf {
|
||||||
|
home_dir().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
pub mod editor {
|
||||||
|
use crate::structs::LKErr;
|
||||||
|
use rustyline::error::ReadlineError;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Editor {
|
||||||
|
editor: rustyline::Editor<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Editor {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { editor: rustyline::Editor::<()>::new().unwrap() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_history(&mut self) {
|
||||||
|
self.editor.clear_history();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_history_entry(&mut self, entry: &str) {
|
||||||
|
self.editor.add_history_entry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_history<'a>(&mut self, fname: &str) -> Result<(), LKErr<'a>> {
|
||||||
|
match self.editor.load_history(&fname) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(_) => Err(LKErr::Error("failed to read history file")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_history<'a>(&mut self, fname: &str) -> Result<(), LKErr<'a>> {
|
||||||
|
match self.editor.save_history(&fname) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(ReadlineError::Eof | ReadlineError::Interrupted) => Err(LKErr::EOF),
|
||||||
|
Err(_) => Err(LKErr::Error("failed to write history file")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readline<'a>(&mut self, prompt: &str) -> Result<String, LKErr<'a>> {
|
||||||
|
match self.editor.readline(&prompt) {
|
||||||
|
Ok(line) => Ok(line),
|
||||||
|
Err(_) => Err(LKErr::Error("failed to read from input")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call_cmd_with_input(cmd: &str, args: &Vec<String>, input: &str) -> io::Result<String> {
|
||||||
|
let mut cmd = Command::new(cmd).args(args).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
||||||
|
let mut stdin = cmd.stdin.take().unwrap();
|
||||||
|
let stdout = cmd.stdout.as_mut().unwrap();
|
||||||
|
let in_data = input.to_string();
|
||||||
|
let write_handle = std::thread::spawn(move || stdin.write_all(in_data.as_bytes()));
|
||||||
|
let mut output = Vec::new();
|
||||||
|
stdout.read_to_end(&mut output)?;
|
||||||
|
match write_handle.join() {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "Failed to run command")),
|
||||||
|
}
|
||||||
|
match String::from_utf8(output) {
|
||||||
|
Ok(x) => Ok(x),
|
||||||
|
Err(err) => Err(io::Error::new(io::ErrorKind::InvalidData, err.utf8_error())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_cmd_args_from_command(command: &str) -> io::Result<(String, Vec<String>)> {
|
||||||
|
let args = match split(command) {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidData,
|
||||||
|
format!("Failed to parse the command: {:?}", command),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok((shellexpand::full(&args[0]).unwrap().into_owned(), args[1..].to_vec()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_copy_command_from_env() -> (String, Vec<String>) {
|
||||||
|
let cmd_os_str = env::var_os("HEL_PB").unwrap_or_else(|| match env::consts::OS {
|
||||||
|
_ if env::var("TMUX").is_ok() => OsString::from("tmux load-buffer -"),
|
||||||
|
"macos" => OsString::from("pbcopy"),
|
||||||
|
"linux" => OsString::from("xclip"),
|
||||||
|
_ => OsString::from("cat"),
|
||||||
|
});
|
||||||
|
get_cmd_args_from_command(&cmd_os_str.to_string_lossy()).unwrap_or_else(|_| ("cat".to_string(), vec![]))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cmd_exec_test() {
|
||||||
|
assert_eq!(call_cmd_with_input("true", &vec![], "").unwrap(), "".to_string());
|
||||||
|
assert_eq!(call_cmd_with_input("cat", &vec![], "ok").unwrap(), "ok".to_string());
|
||||||
|
assert_eq!(
|
||||||
|
call_cmd_with_input(
|
||||||
|
"cat",
|
||||||
|
&vec![],
|
||||||
|
r###"line 1
|
||||||
|
line 2
|
||||||
|
line 3
|
||||||
|
line 4"###
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
"line 1\nline 2\nline 3\nline 4".to_string()
|
||||||
|
);
|
||||||
|
assert_ne!(call_cmd_with_input("cat", &vec![], "notok").unwrap(), "ok".to_string());
|
||||||
|
assert_eq!(
|
||||||
|
call_cmd_with_input("echo", &vec!["-n".to_string(), "test is ok".to_string()], "").unwrap(),
|
||||||
|
"test is ok".to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "helcli"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ok2"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "hel"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
hel = { version = "0.1.0", path = "../hel" }
|
||||||
|
rustyline = "10.0.0"
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
extern crate hel;
|
||||||
|
|
||||||
|
use hel::structs::init;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let mut lkread = match init() { Some(r) => r, None => { return; } };
|
||||||
|
|
||||||
|
while lkread.read().eval().print() {
|
||||||
|
lkread.refresh();
|
||||||
|
}
|
||||||
|
lkread.quit();
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "helwasm"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["ok2"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[target.'cfg(wasm32)']
|
||||||
|
[lib]
|
||||||
|
name = "helwasm"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
hel = { version = "0.1.0", path = "../hel" }
|
||||||
|
wasm-bindgen = "0.2.83"
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
extern crate hel;
|
||||||
|
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn add(a: i32, b: i32) -> i32 {
|
||||||
|
a + b + 1
|
||||||
|
}
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
#![recursion_limit = "1024"]
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
#[macro_use(defer)]
|
|
||||||
extern crate scopeguard;
|
|
||||||
|
|
||||||
mod commands;
|
|
||||||
mod lk;
|
|
||||||
mod parser;
|
|
||||||
mod password;
|
|
||||||
mod repl;
|
|
||||||
mod skey;
|
|
||||||
mod structs;
|
|
||||||
mod utils;
|
|
||||||
|
|
||||||
use crate::structs::init;
|
|
||||||
|
|
||||||
pub fn main() {
|
|
||||||
let mut lkread = match init() { Some(r) => r, None => { return; } };
|
|
||||||
|
|
||||||
while lkread.read().eval().print() {
|
|
||||||
lkread.refresh();
|
|
||||||
}
|
|
||||||
lkread.quit();
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
use shlex::split;
|
|
||||||
use std::env;
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::io;
|
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::process::{Command, Stdio};
|
|
||||||
|
|
||||||
pub fn call_cmd_with_input(cmd: &str, args: &Vec<String>, input: &str) -> io::Result<String> {
|
|
||||||
let mut cmd = Command::new(cmd).args(args).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
|
||||||
let mut stdin = cmd.stdin.take().unwrap();
|
|
||||||
let stdout = cmd.stdout.as_mut().unwrap();
|
|
||||||
let in_data = input.to_string();
|
|
||||||
let write_handle = std::thread::spawn(move || stdin.write_all(in_data.as_bytes()));
|
|
||||||
let mut output = Vec::new();
|
|
||||||
stdout.read_to_end(&mut output)?;
|
|
||||||
match write_handle.join() {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "Failed to run command")),
|
|
||||||
}
|
|
||||||
match String::from_utf8(output) {
|
|
||||||
Ok(x) => Ok(x),
|
|
||||||
Err(err) => Err(io::Error::new(io::ErrorKind::InvalidData, err.utf8_error())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_cmd_args_from_command(command: &str) -> io::Result<(String, Vec<String>)> {
|
|
||||||
let args = match split(command) {
|
|
||||||
Some(c) => c,
|
|
||||||
None => {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::InvalidData,
|
|
||||||
format!("Failed to parse the command: {:?}", command),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok((shellexpand::full(&args[0]).unwrap().into_owned(), args[1..].to_vec()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_copy_command_from_env() -> (String, Vec<String>) {
|
|
||||||
let cmd_os_str = env::var_os("HEL_PB").unwrap_or_else(|| match env::consts::OS {
|
|
||||||
_ if env::var("TMUX").is_ok() => OsString::from("tmux load-buffer -"),
|
|
||||||
"macos" => OsString::from("pbcopy"),
|
|
||||||
"linux" => OsString::from("xclip"),
|
|
||||||
_ => OsString::from("cat"),
|
|
||||||
});
|
|
||||||
get_cmd_args_from_command(&cmd_os_str.to_string_lossy()).unwrap_or_else(|_| ("cat".to_string(), vec![]))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cmd_exec_test() {
|
|
||||||
assert_eq!(call_cmd_with_input("true", &vec![], "").unwrap(), "".to_string());
|
|
||||||
assert_eq!(call_cmd_with_input("cat", &vec![], "ok").unwrap(), "ok".to_string());
|
|
||||||
assert_eq!(
|
|
||||||
call_cmd_with_input(
|
|
||||||
"cat",
|
|
||||||
&vec![],
|
|
||||||
r###"line 1
|
|
||||||
line 2
|
|
||||||
line 3
|
|
||||||
line 4"###
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
"line 1\nline 2\nline 3\nline 4".to_string()
|
|
||||||
);
|
|
||||||
assert_ne!(call_cmd_with_input("cat", &vec![], "notok").unwrap(), "ok".to_string());
|
|
||||||
assert_eq!(
|
|
||||||
call_cmd_with_input("echo", &vec!["-n".to_string(), "test is ok".to_string()], "").unwrap(),
|
|
||||||
"test is ok".to_string()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user