use anyhow::Result;
use std::process::Command;
#[allow(dead_code)]
#[cfg(unix)]
pub fn open_external_program(program: &str, path: &str) -> Result<()> {
let shell_cmd = format!(
"{} '{}' < /dev/tty > /dev/tty 2> /dev/tty",
program,
path.replace("'", "'\\''")
);
Command::new("sh").arg("-c").arg(&shell_cmd).status()?;
Ok(())
}
#[allow(dead_code)]
#[cfg(windows)]
pub fn open_external_program(program: &str, path: &str) -> Result<()> {
if program.contains("explorer") || program.contains("start") {
Command::new("cmd")
.args(["/C", "start", "", path])
.spawn()?; } else {
let quoted_path = if path.contains(' ') {
format!("\"{}\"", path)
} else {
path.to_string()
};
Command::new("cmd")
.args(["/C", program, "ed_path])
.status()?;
}
Ok(())
}
#[cfg(unix)]
pub fn is_absolute_path(path: &str) -> bool {
path.starts_with('/') || path.starts_with('.')
}
#[cfg(windows)]
pub fn is_absolute_path(path: &str) -> bool {
path.len() >= 2
&& ((path.chars().nth(1) == Some(':')) || path.starts_with("\\\\")) }
#[cfg(unix)]
#[cfg_attr(not(test), allow(dead_code))]
pub fn normalize_path_separator(path: &str) -> String {
path.to_string()
}
#[cfg(windows)]
#[cfg_attr(not(test), allow(dead_code))]
pub fn normalize_path_separator(path: &str) -> String {
path.replace('/', "\\")
}
pub fn canonicalize_and_normalize(
path: &std::path::Path,
) -> Result<std::path::PathBuf, std::io::Error> {
let canonical = path.canonicalize()?;
#[cfg(windows)]
{
let path_str = canonical.to_string_lossy();
if let Some(normalized) = path_str.strip_prefix("\\\\?\\") {
return Ok(std::path::PathBuf::from(normalized));
}
}
Ok(canonical)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_absolute_path() {
#[cfg(unix)]
{
assert!(is_absolute_path("/home/user"));
assert!(is_absolute_path("./relative"));
assert!(is_absolute_path("../parent"));
assert!(!is_absolute_path("relative"));
assert!(!is_absolute_path("dir/subdir"));
}
#[cfg(windows)]
{
assert!(is_absolute_path("C:\\Users\\user"));
assert!(is_absolute_path("D:\\Projects"));
assert!(is_absolute_path("\\\\server\\share"));
assert!(!is_absolute_path("relative\\path")); assert!(!is_absolute_path("subdir\\child"));
assert!(!is_absolute_path("relative"));
}
}
#[test]
fn test_normalize_path_separator() {
#[cfg(unix)]
{
assert_eq!(normalize_path_separator("path/to/file"), "path/to/file");
assert_eq!(normalize_path_separator("path\\to\\file"), "path\\to\\file");
}
#[cfg(windows)]
{
assert_eq!(normalize_path_separator("path/to/file"), "path\\to\\file");
assert_eq!(normalize_path_separator("path\\to\\file"), "path\\to\\file");
}
}
}