feat(ash): rework command handling
This commit is contained in:
parent
4c6ac174ff
commit
6d93a1d4f6
5 changed files with 79 additions and 31 deletions
|
|
@ -1,53 +1,51 @@
|
|||
use boxutils::commands::Command;
|
||||
use std::env;
|
||||
use std::io::{self, ErrorKind, Write};
|
||||
use std::path::Path;
|
||||
use std::process::Command as stdCommand;
|
||||
use std::io::{self, Write};
|
||||
use std::process;
|
||||
|
||||
use crate::built_in::{Action, run_if_exists};
|
||||
|
||||
pub struct Ash;
|
||||
|
||||
impl Command for Ash {
|
||||
fn execute(&self) {
|
||||
let mut path = env::current_dir().unwrap().display().to_string();
|
||||
|
||||
loop {
|
||||
let path = env::current_dir();
|
||||
let userchar = if boxutils::cross::user::is_admin() {
|
||||
'#'
|
||||
} else {
|
||||
'$'
|
||||
};
|
||||
print!("{} {} ", path.expect("unknown").display(), userchar);
|
||||
print!("{} {} ", path.clone(), userchar);
|
||||
let _ = io::stdout().flush();
|
||||
let mut input = String::new();
|
||||
io::stdin().read_line(&mut input).unwrap();
|
||||
let mut full_cmd = input.trim().split_whitespace();
|
||||
let command = full_cmd.next().unwrap();
|
||||
let mut arguments = full_cmd;
|
||||
match command {
|
||||
"exit" => return,
|
||||
"cd" => {
|
||||
let new_path = arguments.next();
|
||||
let new_path = Path::new(new_path.unwrap());
|
||||
let _ = env::set_current_dir(&new_path).is_ok();
|
||||
let command = full_cmd.next().unwrap_or(" ");
|
||||
let arguments: Vec<&str> = full_cmd.collect();
|
||||
|
||||
if let Some(action) = run_if_exists(command.to_string(), arguments.clone()) {
|
||||
match action {
|
||||
Action::Exit => {
|
||||
break;
|
||||
}
|
||||
command => {
|
||||
let out = stdCommand::new(command).args(arguments).spawn();
|
||||
|
||||
Action::ChangeDirectory(directory) => {
|
||||
path = directory;
|
||||
env::set_current_dir(&path).unwrap();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let out = process::Command::new(command)
|
||||
.args(arguments.clone())
|
||||
.spawn();
|
||||
|
||||
match out {
|
||||
Ok(mut out) => {
|
||||
let _ = out.wait();
|
||||
}
|
||||
Err(err) => match err.kind() {
|
||||
ErrorKind::NotFound => {
|
||||
eprintln!("ash: {}: not found", command);
|
||||
}
|
||||
ErrorKind::PermissionDenied => {
|
||||
eprintln!("ash: {}: permission denied", command);
|
||||
}
|
||||
_ => {
|
||||
eprintln!("ash: uncaught error: {}", err);
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(err) => println!("{:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
9
shell/src/built_in/cd.rs
Normal file
9
shell/src/built_in/cd.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
use crate::built_in::Action;
|
||||
|
||||
pub fn cd(arguments: Vec<&str>) -> Action {
|
||||
if arguments.len() < 1 {
|
||||
panic!("cd expects **one** argument");
|
||||
}
|
||||
|
||||
Action::ChangeDirectory(arguments[0].to_owned().clone())
|
||||
}
|
||||
5
shell/src/built_in/exit.rs
Normal file
5
shell/src/built_in/exit.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
use crate::built_in::Action;
|
||||
|
||||
pub fn exit(_: Vec<&str>) -> Action {
|
||||
Action::Exit
|
||||
}
|
||||
35
shell/src/built_in/mod.rs
Normal file
35
shell/src/built_in/mod.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
mod cd;
|
||||
mod exit;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Action {
|
||||
Exit,
|
||||
ChangeDirectory(String),
|
||||
}
|
||||
|
||||
fn get_function(command: String) -> Option<fn(Vec<&str>) -> Action> {
|
||||
let registry = [
|
||||
("exit", exit::exit as fn(Vec<&str>) -> Action),
|
||||
("cd", cd::cd as fn(Vec<&str>) -> Action),
|
||||
];
|
||||
let mut function: Option<fn(Vec<&str>) -> Action> = None;
|
||||
|
||||
for entry in registry {
|
||||
if entry.0 == &command {
|
||||
function = Some(entry.1)
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
}
|
||||
|
||||
pub fn run_if_exists(command: String, arguments: Vec<&str>) -> Option<Action> {
|
||||
let function = get_function(command);
|
||||
if let Some(function) = function {
|
||||
let action = function(arguments);
|
||||
|
||||
Some(action)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
pub mod ash;
|
||||
mod built_in;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue