diff options
author | Jesse Luehrs <doy@tozt.net> | 2021-11-18 00:40:01 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2021-11-18 00:40:11 -0500 |
commit | 04068bf2ad233748af1ac98edb12a27bf8ffca75 (patch) | |
tree | 83c398bbcbbb534f837a5fe2d43fbcdefd31e910 /src/builtins.rs | |
parent | 0d0eb5fe9ac69743d85e163106a6df7a1859913d (diff) | |
download | nbsh-04068bf2ad233748af1ac98edb12a27bf8ffca75.tar.gz nbsh-04068bf2ad233748af1ac98edb12a27bf8ffca75.zip |
implement cd
Diffstat (limited to 'src/builtins.rs')
-rw-r--r-- | src/builtins.rs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/builtins.rs b/src/builtins.rs new file mode 100644 index 0000000..225ef5b --- /dev/null +++ b/src/builtins.rs @@ -0,0 +1,44 @@ +pub fn is(exe: &str) -> bool { + matches!(exe, "cd") +} + +pub fn run(exe: &str, args: &[String]) -> u8 { + match exe { + "cd" => { + impls::cd(args.iter().map(|s| s.as_ref()).next().unwrap_or("")) + } + _ => unreachable!(), + } +} + +mod impls { + pub fn cd(dir: &str) -> u8 { + let dir = if dir.is_empty() { + home() + } else if dir.starts_with('~') { + let path: std::path::PathBuf = dir.into(); + if let std::path::Component::Normal(prefix) = + path.components().next().unwrap() + { + if prefix.to_str() == Some("~") { + home().join(path.strip_prefix(prefix).unwrap()) + } else { + // TODO + return 1; + } + } else { + unreachable!() + } + } else { + dir.into() + }; + match std::env::set_current_dir(dir) { + Ok(()) => 0, + Err(_) => 1, + } + } + + fn home() -> std::path::PathBuf { + std::env::var_os("HOME").unwrap().into() + } +} |