use super::*;
#[derive(Clone, Copy)]
pub(crate) enum ShellKind {
Cmd,
Other,
Powershell,
}
impl ShellKind {
pub(crate) fn extension(self) -> &'static str {
match self {
Self::Cmd => ".bat",
Self::Powershell => ".ps1",
Self::Other => "",
}
}
pub(crate) fn takes_shell_name(self) -> bool {
match self {
Self::Cmd | Self::Powershell => false,
Self::Other => true,
}
}
}
impl From<&str> for ShellKind {
fn from(command: &str) -> Self {
match command {
"cmd" | "cmd.exe" => Self::Cmd,
"powershell" | "powershell.exe" | "pwsh" | "pwsh.exe" => Self::Powershell,
_ => Self::Other,
}
}
}
impl From<&Command> for ShellKind {
fn from(command: &Command) -> Self {
let Some(command) = Path::new(command.get_program())
.file_name()
.and_then(OsStr::to_str)
else {
return Self::Other;
};
command.into()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_str() {
#[track_caller]
fn case(s: &str, takes_shell_name: bool, extension: &str) {
let kind = ShellKind::from(s);
assert_eq!(
kind.takes_shell_name(),
takes_shell_name,
"takes_shell_name for {s:?}"
);
assert_eq!(kind.extension(), extension, "extension for {s:?}");
}
case("foo", true, "");
case("cmd", false, ".bat");
case("cmd.exe", false, ".bat");
case("powershell", false, ".ps1");
case("powershell.exe", false, ".ps1");
case("pwsh", false, ".ps1");
case("pwsh.exe", false, ".ps1");
}
}