use std::ffi::{OsString, OsStr};
use std::convert::AsRef;
use std::env::var_os;
pub enum Shell {
Windows,
Bash,
Tcsh,
Zsh,
Ksh,
}
pub fn get_shell() -> Shell {
if cfg!(windows) {
Shell::Windows
} else {
if let Some(shell) = var_os("BASH") {
if shell.to_string_lossy().ends_with("/bash") {
return Shell::Bash;
}
}
if let Some(zsh) = var_os("ZSH_NAME") {
if zsh.to_string_lossy() == "zsh" {
return Shell::Zsh;
}
}
if let Some(shell) = var_os("shell") {
if shell.to_string_lossy().ends_with("/tcsh") {
return Shell::Tcsh;
}
}
return match var_os("SHELL") {
None => Shell::Bash,
Some(oss) => {
if oss.to_string_lossy().ends_with("/bash") {
Shell::Bash
} else if oss.to_string_lossy().ends_with("/ksh") {
Shell::Ksh
} else if oss.to_string_lossy().ends_with("/zsh") {
Shell::Zsh
} else if oss.to_string_lossy().ends_with("/tcsh") {
Shell::Tcsh
} else {
Shell::Bash
} }
};
}
}
impl Shell {
pub fn get_name(&self) -> &'static str {
match *self {
Shell::Windows => "Windows",
Shell::Bash => "bash",
Shell::Tcsh => "tcsh",
Shell::Zsh => "zsh",
Shell::Ksh => "ksh"
}
}
pub fn cd<P: AsRef<OsStr>>(&self, p: P) {
match *self {
Shell::Windows => {
println!("cd /d \"{}\"", p.as_ref().to_string_lossy());
}
_ => {
println!("cd '{}';", p.as_ref().to_string_lossy());
}
}
}
pub fn setenv<K: AsRef<OsStr>, V: AsRef<OsStr>>(&self, k: K, v: V) {
match *self {
Shell::Windows => {
println!("set {}={}",
k.as_ref().to_string_lossy(),
v.as_ref().to_string_lossy())
}
Shell::Tcsh => {
println!("setenv {} '{}';",
k.as_ref().to_string_lossy(),
v.as_ref().to_string_lossy())
}
_ => {
println!("export {}='{}';",
k.as_ref().to_string_lossy(),
v.as_ref().to_string_lossy())
}
}
}
pub fn split_env<K: AsRef<OsStr>>(&self, k: K) -> Vec<OsString> {
match std::env::var(k) {
Err(..) => Vec::new(),
Ok(ref v) => std::env::split_paths(v).map(|p| p.into_os_string()).collect(),
}
}
pub fn setenv_list<K, I, T>(&self, k: K, v: I)
where K: AsRef<OsStr>,
I: IntoIterator<Item = T>,
T: AsRef<OsStr>
{
let paths = std::env::join_paths(v).unwrap();
self.setenv(k, paths);
}
}