summaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: b1fb7b7a0391814bfb695bc70efec4e89ee90c80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std::io::{self,stdin,stdout,Write};
use std::str::FromStr;
use std::process::{Command};
use std::env;
use std::path::Path;

fn substitute_vars(word: &str) -> String {
	match word {
		"~" => env::var("HOME").unwrap(),
		w if w.chars().nth(0).unwrap() == '~' => w.replace("~", env::var("HOME").unwrap().as_str()),
		w if w.chars().nth(0).unwrap() == '$' => {
			match env::var(&w[1..]) {
				Ok(val) => val,
				Err(_) => String::from_str("").unwrap()
			}
		},
		w => String::from_str(w).unwrap()
	}
}

fn main() -> io::Result<()> {
	loop {
		stdout().write_all(b"> ")?;
		stdout().flush()?;
		
		let mut line = String::new();
		stdin().read_line(&mut line).unwrap();

		let tmp = line.trim().split_whitespace()
			.collect::<Vec<&str>>();
		let mut parts = tmp.iter()
			.map(|x| substitute_vars(*x));
		let command = parts.next().unwrap();
		
		match command.as_str() {
			"exit" => return Ok(()),
			"cd" => {
				// change directory
				let new_dir = parts.peekable().peek()
					.map_or(env::var("HOME").unwrap(),
							|x| (*x).clone());
				let new_wd = Path::new(&new_dir);
				if let Err(e) = env::set_current_dir(&new_wd) {
					eprintln!("{}", e);
				}
			},
			command => {
				let child = Command::new(command)
					.args(parts)
					.spawn();

				match child {
					Ok(mut child) => { child.wait()?; },
					Err(e) => eprintln!("{}", e)
				}
			}
		}
	}
}