use crate::os_detect::Os;
pub(crate) fn posix_quote(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 2);
out.push('\'');
for c in s.chars() {
if c == '\'' {
out.push_str("'\\''");
} else {
out.push(c);
}
}
out.push('\'');
out
}
pub(crate) fn powershell_quote(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 2);
out.push('\'');
for c in s.chars() {
if c == '\'' {
out.push('\'');
out.push('\'');
} else {
out.push(c);
}
}
out.push('\'');
out
}
pub(crate) fn quote_for(os: Os, s: &str) -> String {
match os {
Os::Windows => powershell_quote(s),
Os::Macos | Os::Linux | Os::Termux => posix_quote(s),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn posix_quote_wraps_simple_input_in_single_quotes() {
assert_eq!(posix_quote("lazygit"), "'lazygit'");
}
#[test]
fn posix_quote_neutralises_metachars() {
assert_eq!(posix_quote("$(rm -rf ~)"), "'$(rm -rf ~)'");
assert_eq!(posix_quote("a;b`c"), "'a;b`c'");
assert_eq!(posix_quote("with\nnewline"), "'with\nnewline'");
}
#[test]
fn posix_quote_handles_embedded_single_quote() {
assert_eq!(posix_quote("it's"), "'it'\\''s'");
}
#[test]
fn powershell_quote_doubles_inner_single_quotes() {
assert_eq!(powershell_quote("it's"), "'it''s'");
assert_eq!(powershell_quote("plain"), "'plain'");
}
#[test]
fn quote_for_dispatches_by_os() {
assert_eq!(quote_for(Os::Linux, "it's"), "'it'\\''s'");
assert_eq!(quote_for(Os::Macos, "it's"), "'it'\\''s'");
assert_eq!(quote_for(Os::Termux, "it's"), "'it'\\''s'");
assert_eq!(quote_for(Os::Windows, "it's"), "'it''s'");
}
}