use std::{
ffi::OsStr,
io,
process::{Command, Child, ExitStatus},
};
pub const OPEN_TOOL: &str = {
cfg_if! {
if #[cfg(target_os = "macos")] {
let open = "/usr/bin/open";
} else if #[cfg(target_os = "linux")] {
let open = "xdg-open";
} else if #[cfg(target_os = "windows")] {
let open = "start";
} else {
compile_error!(
"No known way of opening a resource on the current platform."
);
}
};
open
};
pub fn open<R>(resources: &[R]) -> io::Result<()>
where R: AsRef<OsStr>
{
fn status_to_result(status: ExitStatus) -> io::Result<()> {
if status.success() {
Ok(())
} else {
Err(io::Error::new(
io::ErrorKind::Other,
format!("Opening finished with status {}", status),
))
}
}
if resources.is_empty() {
return Ok(());
}
if cfg!(target_os = "macos") {
let mut cmd = Command::new(OPEN_TOOL);
cmd.args(resources);
status_to_result(cmd.status()?)
} else {
let children: Vec::<io::Result<Child>> = resources
.iter()
.map(|res| {
let mut cmd = Command::new(OPEN_TOOL);
cmd.arg(res);
cmd.spawn()
})
.collect();
for child in children {
status_to_result(child?.wait()?)?;
}
Ok(())
}
}