Browse Source

Merge remote-tracking branch 'origin/main'

# Conflicts:
#	src/builtins/mod.rs
main
fdai7374 2 years ago
parent
commit
d6c8f5de43
  1. 4
      src/builtins/fetch.rs
  2. 31
      src/builtins/help.rs
  3. 41
      src/builtins/ls.rs
  4. 32
      src/builtins/mod.rs
  5. 36
      src/builtins/time.rs
  6. 10
      src/error.rs
  7. 6
      src/execute.rs

4
src/builtins/fetch.rs

@ -20,7 +20,7 @@ impl Builtin for Fetch {
"@".bold(),
hostname().bright_green().bold()
);
println!("{}", line);
println!("{line}");
println!(
"{} {} {}",
"OS".bright_blue().bold(),
@ -50,7 +50,7 @@ fn format_uptime(uptime: u64) -> String {
let m = (uptime - h * 3600) / 60;
let s = uptime - (h * 3600 + m * 60);
format!("{:.0}h {:.0}m {:.0}s", h, m, s)
format!("{h:.0}h {m:.0}m {s:.0}s")
}
fn bytes_to_mebi_bytes(bytes: u64) -> u64 {

31
src/builtins/help.rs

@ -1,6 +1,6 @@
use colored::Colorize;
use crate::builtins::{Builtin, BuiltinConfig};
use crate::error::ShellError;
use colored::Colorize;
pub struct Help;
@ -21,18 +21,22 @@ impl Builtin for Help {
";
for line in commands.lines() {
println!("{}{}", split_command(line)[0].bold(), split_command(line)[1]);
println!(
"{}{}",
split_command(line)[0].bold(),
split_command(line)[1]
);
}
Ok(())
}
}
fn split_command(commands: &str) -> Vec<&str> {
if commands.trim_start().len() >= 1 {
let splitted_command = commands.trim_start().splitn(2, " ").collect();
if !commands.trim_start().is_empty() {
let splitted_command = commands.trim_start().splitn(2, ' ').collect();
return splitted_command;
}
return vec!["", ""];
vec!["", ""]
}
#[cfg(test)]
@ -42,13 +46,22 @@ mod tests {
#[test]
fn test_split_command_split() {
let test_string1 = "Hallo, Marcel Davis 1&1.";
assert_eq!(split_command(test_string1), vec!["Hallo,", "Marcel Davis 1&1."]);
assert_eq!(
split_command(test_string1),
vec!["Hallo,", "Marcel Davis 1&1."]
);
let test_string2 = "Leiter1 23für Kundenzufriedenheit.";
assert_eq!(split_command(test_string2), vec!["Leiter1", "23für Kundenzufriedenheit."]);
assert_eq!(
split_command(test_string2),
vec!["Leiter1", "23für Kundenzufriedenheit."]
);
let test_string3 = "Wir# $%gehen erst wieder, wenn ihre Leitung läuft!";
assert_eq!(split_command(test_string3), vec!["Wir#", "$%gehen erst wieder, wenn ihre Leitung läuft!"]);
assert_eq!(
split_command(test_string3),
vec!["Wir#", "$%gehen erst wieder, wenn ihre Leitung läuft!"]
);
}
#[test]
@ -60,4 +73,4 @@ mod tests {
fn test_split_command_only_space() {
assert_eq!(split_command(" "), vec!["", ""]);
}
}
}

41
src/builtins/ls.rs

@ -1,4 +1,8 @@
use std::{fs::metadata, path::PathBuf, str::FromStr};
use std::{
fs::{metadata, Permissions},
path::PathBuf,
str::FromStr,
};
use chrono::{DateTime, Datelike, Local};
@ -19,7 +23,7 @@ impl Builtin for Ls {
//for entry in entries.by_ref().into_iter() {}
println!(
"{} | dir | size | modified |",
"{} | dir | size | modified | accessed | created | readonly |",
right_padding(" filename", 20)
);
@ -42,6 +46,18 @@ impl Builtin for Ls {
Err(_) => Local::now(),
};
let accessed: DateTime<Local> = match metadata.accessed() {
Ok(t) => DateTime::from(t),
Err(_) => Local::now(),
};
let created: DateTime<Local> = match metadata.created() {
Ok(t) => DateTime::from(t),
Err(_) => Local::now(),
};
let permissions = metadata.permissions();
let mut file_type = "unknown";
if metadata.file_type().is_dir() {
file_type = "dir"
@ -52,7 +68,16 @@ impl Builtin for Ls {
}
println!(
"{}",
format_line(20, &file_name, file_type, metadata.len(), modified)
format_line(
20,
&file_name,
file_type,
metadata.len(),
modified,
accessed,
created,
permissions
)
);
}
Ok(())
@ -86,13 +111,19 @@ fn format_line(
file_type: &str,
file_size: u64,
modified: DateTime<Local>,
accessed: DateTime<Local>,
created: DateTime<Local>,
permissions: Permissions,
) -> String {
format!(
"{} | {:4} | {:6} | {} |",
"{} | {:4} | {:6} | {:<10} | {:<10} | {:<10} | {:<5} |",
right_padding(file_name, max_name_len),
file_type,
format_filesize(file_size),
right_padding(&format_date(modified), 10)
format_date(modified),
format_date(accessed),
format_date(created),
permissions.readonly().to_string(),
)
}

32
src/builtins/mod.rs

@ -14,6 +14,7 @@ mod pwd;
mod quote;
mod segfault;
mod sus;
mod time;
pub struct BuiltinConfig {
pub prompt_style: PromptStyle,
@ -45,6 +46,8 @@ const BUILTINS: Lazy<Vec<(&str, Box<dyn Builtin>)>> = Lazy::new(|| {
("quote", Box::new(quote::Quote)),
("segfault", Box::new(segfault::Segfault)),
("sus", Box::new(sus::Sus)),
("quote", Box::new(quote::Quote)),
("time", Box::new(time::Time)),
]
});
@ -73,27 +76,27 @@ mod tests {
#[test]
fn test_is_builtin_cd() {
assert_eq!(is_builtin("cd"), true);
assert!(is_builtin("cd"));
}
#[test]
fn test_is_builtin_change_prompt() {
assert_eq!(is_builtin("change-prompt"), true);
assert!(is_builtin("change-prompt"));
}
#[test]
fn test_is_builtin_exit() {
assert_eq!(is_builtin("exit"), true);
assert!(is_builtin("exit"));
}
#[test]
fn test_is_builtin_fetch() {
assert_eq!(is_builtin("fetch"), true);
assert!(is_builtin("fetch"));
}
#[test]
fn test_is_builtin_help() {
assert_eq!(is_builtin("help"), true);
assert!(is_builtin("help"));
}
#[test]
@ -103,36 +106,41 @@ mod tests {
#[test]
fn test_is_builtin_ls() {
assert_eq!(is_builtin("ls"), true);
assert!(is_builtin("ls"));
}
#[test]
fn test_is_builtin_open() {
assert_eq!(is_builtin("open"), true);
assert!(is_builtin("open"));
}
#[test]
fn test_is_builtin_pwd() {
assert_eq!(is_builtin("pwd"), true);
assert!(is_builtin("pwd"));
}
#[test]
fn test_is_builtin_segfault() {
assert_eq!(is_builtin("segfault"), true);
assert!(is_builtin("segfault"));
}
#[test]
fn test_is_builtin_sus() {
assert_eq!(is_builtin("sus"), true);
assert!(is_builtin("sus"));
}
#[test]
fn test_is_builtin_quote() {
assert_eq!(is_builtin("quote"), true);
assert!(is_builtin("quote"));
}
#[test]
fn test_is_builtin_time() {
assert!(is_builtin("time"));
}
#[test]
fn test_is_builtin_notabuiltin() {
assert_eq!(is_builtin("notabuiltin"), false)
assert!(!is_builtin("notabuiltin"))
}
}

36
src/builtins/time.rs

@ -0,0 +1,36 @@
use chrono::{DateTime, Local};
use crate::error::ShellError;
use super::{Builtin, BuiltinConfig};
pub struct Time;
impl Builtin for Time {
fn execute(&mut self, _: &mut BuiltinConfig, args: Vec<String>) -> Result<(), ShellError> {
let time = Local::now();
let formatting = args.get(0).cloned().unwrap_or_default();
let time_string = format_time(time, &formatting);
println!("{time_string}");
Ok(())
}
}
fn format_time(time: DateTime<Local>, formatting: &str) -> String {
match formatting {
"RFC2822" => time.to_rfc2822(),
"RFC3339" => time.to_rfc3339(),
_ => time.format("%T").to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_time() {
assert_eq!(Time.execute(&mut BuiltinConfig::new(), vec![]), Ok(()))
}
}

10
src/error.rs

@ -12,11 +12,11 @@ pub enum ShellError {
impl PartialEq<Self> for ShellError {
fn eq(&self, other: &Self) -> bool {
match self {
&ShellError::EmptyLine => matches!(other, ShellError::EmptyLine),
&ShellError::NotFound(_) => matches!(other, ShellError::NotFound(_)),
&ShellError::ExecuteFailure(_) => matches!(other, ShellError::ExecuteFailure(_)),
&ShellError::MalformedArgs(_) => matches!(other, ShellError::MalformedArgs(_)),
&ShellError::Interrupt => matches!(other, ShellError::Interrupt),
ShellError::EmptyLine => matches!(other, ShellError::EmptyLine),
ShellError::NotFound(_) => matches!(other, ShellError::NotFound(_)),
ShellError::ExecuteFailure(_) => matches!(other, ShellError::ExecuteFailure(_)),
ShellError::MalformedArgs(_) => matches!(other, ShellError::MalformedArgs(_)),
ShellError::Interrupt => matches!(other, ShellError::Interrupt),
}
}
}

6
src/execute.rs

@ -10,16 +10,16 @@ use std::{io, thread};
/// This function is not directly in main.rs because it might be called by other function too (eg.
/// when piping commands).
pub fn interpret(line: String, config: &mut BuiltinConfig, ctrlc_recv: Receiver<()>) {
match try_interpret(line, config, ctrlc_recv.clone()) {
match try_interpret(line, config, ctrlc_recv) {
Ok(_) | Err(ShellError::Interrupt) | Err(ShellError::EmptyLine) => (),
Err(ShellError::NotFound(cmd)) => {
eprintln!("{}: command not found", cmd.get_program().to_string_lossy())
}
Err(ShellError::ExecuteFailure(msg)) => {
eprintln!("{}", msg)
eprintln!("{msg}")
}
Err(ShellError::MalformedArgs(args)) => {
eprintln!("Malformed arguments: {}", args)
eprintln!("Malformed arguments: {args}")
}
}
}

Loading…
Cancel
Save