You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

82 lines
1.7 KiB

use crate::error::ShellError;
use crate::prompt::PromptStyle;
use once_cell::unsync::Lazy;
mod cd;
mod change_prompt;
mod exit;
mod pwd;
pub struct BuiltinConfig {
pub prompt_style: PromptStyle,
}
impl BuiltinConfig {
pub fn new() -> Self {
Self {
prompt_style: PromptStyle::Default,
}
}
}
trait Builtin: Sync + Send {
fn execute(&mut self, config: &mut BuiltinConfig, args: Vec<String>) -> Result<(), ShellError>;
}
const BUILTINS: Lazy<Vec<(&str, Box<dyn Builtin>)>> = Lazy::new(|| {
vec![
("cd", Box::new(cd::Cd)),
("change-prompt", Box::new(change_prompt::ChangePrompt)),
("exit", Box::new(exit::Exit)),
("pwd", Box::new(pwd::Pwd)),
]
});
pub fn is_builtin(keyword: &str) -> bool {
BUILTINS.iter().find(|(k, _)| k == &keyword).is_some()
}
#[allow(const_item_mutation)]
pub fn execute_builtin(
keyword: &str,
config: &mut BuiltinConfig,
args: Vec<String>,
) -> Result<(), ShellError> {
if let Some(builtin) = BUILTINS
.iter_mut()
.find_map(|(k, c)| if k == &keyword { Some(c) } else { None })
{
builtin.execute(config, args)?
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_builtin_exit() {
assert_eq!(is_builtin("exit"), true);
}
#[test]
fn test_is_builtin_cd() {
assert_eq!(is_builtin("cd"), true);
}
#[test]
fn test_is_builtin_pwd() {
assert_eq!(is_builtin("pwd"), true);
}
#[test]
fn test_is_builtin_change_prompt() {
assert_eq!(is_builtin("change-prompt"), true);
}
#[test]
fn test_is_builtin_notabuiltin() {
assert_eq!(is_builtin("notabuiltin"), false)
}
}