use crate::{Shell, Simplified};
use std::path::Path;
pub fn shlex_posix(executable: impl AsRef<Path>) -> String {
let executable = executable.as_ref().portable_display().to_string();
if !executable.is_empty()
&& executable
.bytes()
.all(|byte| byte.is_ascii_alphanumeric() || b"@%+=:,./-_".contains(&byte))
{
executable
} else {
format!("'{}'", escape_posix_for_single_quotes(&executable))
}
}
pub fn escape_posix_for_single_quotes(string: &str) -> String {
string.replace('\'', r#"'"'"'"#)
}
pub fn shlex_windows(executable: impl AsRef<Path>, shell: Shell) -> String {
let executable = executable.as_ref().user_display().to_string();
if executable.contains(' ') {
if shell == Shell::Powershell {
format!("& \"{executable}\"")
} else {
format!("\"{executable}\"")
}
} else {
executable
}
}
#[cfg(test)]
mod tests {
use super::shlex_posix;
#[test]
fn posix_safe_path() {
assert_eq!(shlex_posix("/usr/bin/python3.12"), "/usr/bin/python3.12");
}
#[test]
fn posix_empty_path() {
assert_eq!(shlex_posix(""), "''");
}
#[test]
fn posix_path_with_metacharacters() {
assert_eq!(
shlex_posix("Testing's/$venv;activate"),
r#"'Testing'"'"'s/$venv;activate'"#
);
}
}