Skip to content

Commit 4e552e9

Browse files
authored
feat(ash): rework command handling
2 parents 4c6ac17 + 6d93a1d commit 4e552e9

File tree

5 files changed

+78
-30
lines changed

5 files changed

+78
-30
lines changed

shell/src/ash.rs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,51 @@
11
use boxutils::commands::Command;
22
use std::env;
3-
use std::io::{self, ErrorKind, Write};
4-
use std::path::Path;
5-
use std::process::Command as stdCommand;
3+
use std::io::{self, Write};
4+
use std::process;
5+
6+
use crate::built_in::{Action, run_if_exists};
67

78
pub struct Ash;
89

910
impl Command for Ash {
1011
fn execute(&self) {
12+
let mut path = env::current_dir().unwrap().display().to_string();
13+
1114
loop {
12-
let path = env::current_dir();
1315
let userchar = if boxutils::cross::user::is_admin() {
1416
'#'
1517
} else {
1618
'$'
1719
};
18-
print!("{} {} ", path.expect("unknown").display(), userchar);
20+
print!("{} {} ", path.clone(), userchar);
1921
let _ = io::stdout().flush();
2022
let mut input = String::new();
2123
io::stdin().read_line(&mut input).unwrap();
2224
let mut full_cmd = input.trim().split_whitespace();
23-
let command = full_cmd.next().unwrap();
24-
let mut arguments = full_cmd;
25-
match command {
26-
"exit" => return,
27-
"cd" => {
28-
let new_path = arguments.next();
29-
let new_path = Path::new(new_path.unwrap());
30-
let _ = env::set_current_dir(&new_path).is_ok();
25+
let command = full_cmd.next().unwrap_or(" ");
26+
let arguments: Vec<&str> = full_cmd.collect();
27+
28+
if let Some(action) = run_if_exists(command.to_string(), arguments.clone()) {
29+
match action {
30+
Action::Exit => {
31+
break;
32+
}
33+
34+
Action::ChangeDirectory(directory) => {
35+
path = directory;
36+
env::set_current_dir(&path).unwrap();
37+
}
3138
}
32-
command => {
33-
let out = stdCommand::new(command).args(arguments).spawn();
39+
} else {
40+
let out = process::Command::new(command)
41+
.args(arguments.clone())
42+
.spawn();
3443

35-
match out {
36-
Ok(mut out) => {
37-
let _ = out.wait();
38-
}
39-
Err(err) => match err.kind() {
40-
ErrorKind::NotFound => {
41-
eprintln!("ash: {}: not found", command);
42-
}
43-
ErrorKind::PermissionDenied => {
44-
eprintln!("ash: {}: permission denied", command);
45-
}
46-
_ => {
47-
eprintln!("ash: uncaught error: {}", err);
48-
}
49-
},
44+
match out {
45+
Ok(mut out) => {
46+
let _ = out.wait();
5047
}
48+
Err(err) => println!("{:?}", err),
5149
}
5250
}
5351
}

shell/src/built_in/cd.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use crate::built_in::Action;
2+
3+
pub fn cd(arguments: Vec<&str>) -> Action {
4+
if arguments.len() < 1 {
5+
panic!("cd expects **one** argument");
6+
}
7+
8+
Action::ChangeDirectory(arguments[0].to_owned().clone())
9+
}

shell/src/built_in/exit.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use crate::built_in::Action;
2+
3+
pub fn exit(_: Vec<&str>) -> Action {
4+
Action::Exit
5+
}

shell/src/built_in/mod.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
mod cd;
2+
mod exit;
3+
4+
#[derive(Debug)]
5+
pub enum Action {
6+
Exit,
7+
ChangeDirectory(String),
8+
}
9+
10+
fn get_function(command: String) -> Option<fn(Vec<&str>) -> Action> {
11+
let registry = [
12+
("exit", exit::exit as fn(Vec<&str>) -> Action),
13+
("cd", cd::cd as fn(Vec<&str>) -> Action),
14+
];
15+
let mut function: Option<fn(Vec<&str>) -> Action> = None;
16+
17+
for entry in registry {
18+
if entry.0 == &command {
19+
function = Some(entry.1)
20+
}
21+
}
22+
23+
function
24+
}
25+
26+
pub fn run_if_exists(command: String, arguments: Vec<&str>) -> Option<Action> {
27+
let function = get_function(command);
28+
if let Some(function) = function {
29+
let action = function(arguments);
30+
31+
Some(action)
32+
} else {
33+
None
34+
}
35+
}

shell/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pub mod ash;
2+
mod built_in;

0 commit comments

Comments
 (0)