Added signs replacement (homedir and previous command) and reformatted

This commit is contained in:
Justine 2022-12-12 17:19:20 +01:00
parent 835772aaa3
commit 07f50c6f9b

View File

@ -121,22 +121,34 @@ fn print_history() -> Result<(), std::io::Error> {
fn get_hist_from_number(number: &i32) -> Option<String> { fn get_hist_from_number(number: &i32) -> Option<String> {
//Returns a command from its number in hist file //Returns a command from its number in hist file
let filepath = dirs::home_dir().unwrap().join("history.rshell"); let filepath = dirs::home_dir().unwrap().join("history.rshell");
if filepath.exists() {
let file = File::open(filepath).expect("Error opening history file, should NOT happen"); if filepath.exists() == false {
let mut reader = BufReader::new(file).lines();
for line in reader {
let current_line = line.expect("Empty history file ? Please rm it");
let mut s = current_line.split_whitespace();
let n: i32 = s.next().expect("Error reading a line in hist file").parse().unwrap();
let c = s.next().expect("No command!");
if &n == number {
return Some(String::from(c));
}
}
return None;
} else {
return None; return None;
} }
let file = File::open(filepath)
.expect("Error opening history file...");
if file.metadata().unwrap().len() < 1 {
return None;
}
let mut reader = BufReader::new(file).lines();
for line in reader {
let current_line = line
.expect("Empty history file ? Please rm it");
let mut s = current_line.split_whitespace();
let n: i32 = s.next()
.expect("Error reading a line in hist file")
.parse()
.unwrap();
let c = s.next().expect("No command!");
if &n == number {
return Some(String::from(c));
}
}
return None;
} }
fn treat_history_callback(line: &str) -> Option<String> { fn treat_history_callback(line: &str) -> Option<String> {
@ -181,30 +193,48 @@ fn build_prompt() -> String {
return prompt; return prompt;
} }
fn replace_signs(line: String) -> String {
let mut ayo = String::from(&line);
if ayo.contains('~') {
let homedir = dirs::home_dir().unwrap().into_os_string().into_string().unwrap();
let result = str::replace(&ayo, "~", &homedir);
ayo = String::from(result);
}
if ayo.contains("!!") {
let prev_comm = get_hist_from_number(&get_history_number().unwrap()).unwrap();
let result = str::replace(&ayo, "!!", &prev_comm);
ayo = String::from(result);
}
return ayo;
}
fn main(){ fn main(){
loop { loop {
print!("{}", build_prompt()); print!("{}", build_prompt());
stdout().flush(); stdout().flush();
let mut input = String::new(); let mut input = String::new();
let bytes = stdin().read_line(&mut input).unwrap(); let bytes = stdin().read_line(&mut input).unwrap();
if (bytes > 0) && (input != String::from("\n")) { input = replace_signs(input);
if input.starts_with("!") {
let command_found = treat_history_callback(&input); //history callback
match command_found { if (bytes > 0) && (input != String::from("\n")) && (input.starts_with('!')) {
Some(c) => { let command_found = treat_history_callback(&input);
write_to_history(&c); match command_found {
process_line(c); Some(c) => {
write_to_history(&c);
process_line(c);
}, },
None => () None => ()
}; };
} else { //Regular command
write_to_history(&input); } else if (bytes > 0) && (input != String::from("\n")) {
if process_line(input) { write_to_history(&input);
return if process_line(input) {
} return
} }
//Nothing
} else { } else {
//Command was empty, new line //Command was empty, new line
continue; continue;
@ -220,16 +250,17 @@ mod tests {
fn inittests() { fn inittests() {
let filepath = dirs::home_dir().unwrap().join("history.rshell"); let filepath = dirs::home_dir().unwrap().join("history.rshell");
//if the file exists, new will truncate it
let file = File::create(&filepath).expect("Could not create test history"); let file = File::create(&filepath).expect("Could not create test history");
writeln!(&file, "1 ls"); writeln!(&file, "1 ls");
writeln!(&file, "2 pwd");
} }
#[test] #[test]
fn test_gethistnumber() { fn test_gethistnumber() {
inittests(); inittests();
let mynumber = get_history_number().unwrap(); let mynumber = get_history_number().unwrap();
assert_eq!(mynumber, 1); assert_eq!(mynumber, 2);
} }
#[test] #[test]
@ -239,6 +270,20 @@ mod tests {
assert_eq!(mycmd, String::from("ls")); assert_eq!(mycmd, String::from("ls"));
} }
#[test]
fn test_history_callback() {
inittests();
let expected = String::from("ls");
assert_eq!(treat_history_callback("!1"), Some(expected));
}
#[test]
fn test_replace_signs() {
inittests();
let homedir = dirs::home_dir().unwrap().into_os_string().into_string().unwrap();
assert_eq!(replace_signs(String::from("ls ~ && echo !!")), String::from(format!("ls {} && echo pwd", homedir)));
}
#[test] #[test]
fn test_writehistline() { fn test_writehistline() {
inittests(); inittests();
@ -250,18 +295,11 @@ mod tests {
let file = File::open(filepath).expect("Error"); let file = File::open(filepath).expect("Error");
let mut reader = BufReader::new(file).lines(); let mut reader = BufReader::new(file).lines();
let myline = String::from(reader.last().unwrap().expect("Error")); let myline = String::from(reader.last().unwrap().expect("Error"));
let expected = String::from("2 pwd"); let expected = String::from("3 pwd");
assert_eq!(myline.trim(), expected.trim()); assert_eq!(myline.trim(), expected.trim());
} }
#[test]
fn test_history_callback() {
inittests();
let expected = String::from("ls");
assert_eq!(treat_history_callback("!1"), Some(expected));
}
} }