summaryrefslogtreecommitdiffstats
path: root/src/builtins.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-11-18 00:40:01 -0500
committerJesse Luehrs <doy@tozt.net>2021-11-18 00:40:11 -0500
commit04068bf2ad233748af1ac98edb12a27bf8ffca75 (patch)
tree83c398bbcbbb534f837a5fe2d43fbcdefd31e910 /src/builtins.rs
parent0d0eb5fe9ac69743d85e163106a6df7a1859913d (diff)
downloadnbsh-04068bf2ad233748af1ac98edb12a27bf8ffca75.tar.gz
nbsh-04068bf2ad233748af1ac98edb12a27bf8ffca75.zip
implement cd
Diffstat (limited to 'src/builtins.rs')
-rw-r--r--src/builtins.rs44
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()
+ }
+}