|
|
@ -1,18 +1,26 @@ |
|
|
|
use crate::error::ShellError;
|
|
|
|
use once_cell::unsync::Lazy;
|
|
|
|
mod cd;
|
|
|
|
mod exit;
|
|
|
|
|
|
|
|
const BUILTINS: &[&str] = &["exit", "cd"];
|
|
|
|
trait Builtin: Sync + Send {
|
|
|
|
fn execute(&mut self, args: Vec<String>) -> Result<(), ShellError>;
|
|
|
|
}
|
|
|
|
|
|
|
|
const BUILTINS: Lazy<Vec<(&str, Box<dyn Builtin>)>> =
|
|
|
|
Lazy::new(|| vec![("cd", Box::new(cd::Cd)), ("exit", Box::new(exit::Exit))]);
|
|
|
|
|
|
|
|
pub fn is_builtin(keyword: &str) -> bool {
|
|
|
|
BUILTINS.contains(&keyword)
|
|
|
|
BUILTINS.iter().find(|(k, _)| k == &keyword).is_some()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(const_item_mutation)]
|
|
|
|
pub fn execute_builtin(keyword: &str, args: Vec<String>) -> Result<(), ShellError> {
|
|
|
|
match keyword {
|
|
|
|
"exit" => exit::run()?,
|
|
|
|
"cd" => cd::run(args)?,
|
|
|
|
_ => {}
|
|
|
|
if let Some(builtin) = BUILTINS
|
|
|
|
.iter_mut()
|
|
|
|
.find_map(|(k, c)| if k == &keyword { Some(c) } else { None })
|
|
|
|
{
|
|
|
|
builtin.execute(args)?
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|