use std::env; use std::os::unix::process::ExitStatusExt; use std::process::{ExitStatus, Output}; /// cd /// /// The builtin `cd` command. Used to change directories. This must be /// implemented by the shell, since the `pwd` is context sensitive within a /// process. If no arguments are given, `cd` will take the user back to their /// home directory (i.e. `~`). /// /// # Shell Example /// ```sh /// cd ~/.config # Change into /home//.config /// ``` pub fn incant(clause: &Option>, uerr: bool) -> Output { let status; let out: Vec = Vec::new(); let mut err: Vec = Vec::new(); let path = match clause { Some(path) => path[0].to_string(), None => match env::var("HOME") { Ok(val) => val, Err(_) => { status = 1; if uerr { err.append(&mut "cd: unknown home, staying in pwd\n".as_bytes().to_vec()); } else { eprintln!("cd: unknown home, staying in pwd"); } return Output { status: ExitStatus::from_raw(status), stdout: out, stderr: err, }; } }, }; status = match std::env::set_current_dir(&path) { Ok(_) => 0, Err(e) => { if uerr { err.append( &mut format!( "cd: unable to change into {}: {}\n", path, e.to_string().to_lowercase() ) .as_bytes() .to_vec(), ); } else { eprintln!( "cd: unable to change into {}: {}", path, e.to_string().to_lowercase() ); } 1 } }; Output { status: ExitStatus::from_raw(status), stdout: out, stderr: err, } }