use crate::{
builtins::{Builtin, BuiltinFuture, BuiltinRegistry},
shell::{CommandOutput, ExitCode, SharedShellState, ShellAction},
};
pub struct TypeBuiltin;
impl Builtin for TypeBuiltin {
fn name(&self) -> &'static str {
"type"
}
fn execute<'a>(&'a self, state: SharedShellState, args: &'a [String]) -> BuiltinFuture<'a> {
Box::pin(async move {
if args.len() != 1 {
return Ok(ShellAction::continue_with(CommandOutput {
exit_code: ExitCode::FAILURE,
stdout: String::new(),
stderr: "type: expected exactly one argument\n".to_string(),
}));
}
let needle = &args[0];
let registry = BuiltinRegistry::defaults();
if let Some(value) = state.read().await.aliases().get(needle).map(str::to_owned) {
return Ok(ShellAction::continue_with(CommandOutput {
exit_code: ExitCode::SUCCESS,
stdout: format!("{needle} is aliased to `{value}`\n"),
stderr: String::new(),
}));
}
if state.read().await.functions().get(needle).is_some() {
return Ok(ShellAction::continue_with(CommandOutput {
exit_code: ExitCode::SUCCESS,
stdout: format!("{needle} is a shell function\n"),
stderr: String::new(),
}));
}
if registry.contains(needle) {
return Ok(ShellAction::continue_with(CommandOutput {
exit_code: ExitCode::SUCCESS,
stdout: format!("{needle} is a shell builtin\n"),
stderr: String::new(),
}));
}
Ok(ShellAction::continue_with(CommandOutput {
exit_code: ExitCode::FAILURE,
stdout: String::new(),
stderr: format!("type: {needle} not found\n"),
}))
})
}
}