diff --git a/src/command/builtin.rs b/src/command/builtin.rs new file mode 100644 index 0000000..5abc0d3 --- /dev/null +++ b/src/command/builtin.rs @@ -0,0 +1,63 @@ +use super::Command; +use crate::{error::print_error, exit_code::ExitCode}; + +use std::env; +use std::{env::set_current_dir, path::PathBuf}; + +type BuiltinFunction = fn(&Vec) -> ExitCode; + +pub struct Builtin { + function: BuiltinFunction, + args: Vec, +} + +impl Builtin { + pub fn new(argv: &Vec) -> Result { + let mut args = argv.clone(); + let program = args.remove(0); + + if program == "cd" { + Ok(Self { function: cd, args }) + } else { + Err(NoSuchBuiltinError) + } + } +} + +impl Command for Builtin { + fn spawn(&mut self) -> ExitCode { + (self.function)(&self.args) + } +} + +#[derive(Debug)] +pub struct NoSuchBuiltinError; + +fn cd(args: &Vec) -> ExitCode { + let path: Option; + + if !args.is_empty() { + path = Some(PathBuf::from(&args[0])); + } else { + path = match env::var("HOME") { + Ok(var) => Some(PathBuf::from(var)), + Err(_e) => None, + }; + } + + let exit_code: ExitCode; + if path.is_some() { + exit_code = match set_current_dir(path.unwrap()) { + Ok(()) => ExitCode::success(), + Err(_e) => ExitCode::new(2), + }; + } else { + exit_code = ExitCode::success(); + } + + if exit_code.get() != 0 { + print_error("lol"); + } + + exit_code +}