use std::process::Command;
fn browser_launch_command(url: &str) -> Result<(&'static str, Vec<&str>), String> {
if cfg!(target_os = "macos") {
Ok(("open", vec![url]))
} else if cfg!(target_os = "windows") {
Ok(("rundll32", vec!["url.dll,FileProtocolHandler", url]))
} else if cfg!(target_os = "linux")
|| cfg!(target_os = "freebsd")
|| cfg!(target_os = "openbsd")
|| cfg!(target_os = "netbsd")
{
Ok(("xdg-open", vec![url]))
} else {
Err("Unsupported platform for opening browser".to_string())
}
}
pub fn open_browser(url: &str) -> Result<(), String> {
let (cmd, args) = browser_launch_command(url)?;
match Command::new(cmd).args(&args).spawn() {
Ok(_child) => {
Ok(())
}
Err(e) => {
Err(format!("Failed to open browser: {}", e))
}
}
}
pub fn open_file(path: &str) -> Result<(), String> {
let (cmd, args): (&str, Vec<&str>) = if cfg!(target_os = "macos") {
("open", vec![path])
} else if cfg!(target_os = "windows") {
("rundll32", vec!["url.dll,FileProtocolHandler", path])
} else if cfg!(target_os = "linux")
|| cfg!(target_os = "freebsd")
|| cfg!(target_os = "openbsd")
|| cfg!(target_os = "netbsd")
{
("xdg-open", vec![path])
} else {
return Err(format!("Unsupported platform for opening file"));
};
match Command::new(cmd).args(&args).spawn() {
Ok(_) => Ok(()),
Err(e) => Err(format!("Failed to open file: {}", e)),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_platform_detection() {
let (cmd, args) =
browser_launch_command("https://example.com").expect("supported platform");
if cfg!(target_os = "windows") {
assert_eq!(cmd, "rundll32");
assert_eq!(
args,
vec!["url.dll,FileProtocolHandler", "https://example.com"]
);
} else if cfg!(target_os = "macos") {
assert_eq!(cmd, "open");
assert_eq!(args, vec!["https://example.com"]);
} else {
assert_eq!(cmd, "xdg-open");
assert_eq!(args, vec!["https://example.com"]);
}
}
}