1use std::process::Command;
5
6use thiserror::Error;
7
8use crate::osinfo::Platform;
9use crate::shell::{Resolver, ShellError};
10
11#[derive(Debug, Error)]
13pub enum ProcessError {
14 #[error("process: application path required")]
16 EmptyPath,
17 #[error("process: locate launcher: {0}")]
19 Locate(#[from] ShellError),
20 #[error("process: relaunch: {0}")]
22 Spawn(#[from] std::io::Error),
23}
24
25pub fn relaunch(application_path: &str) -> Result<(), ProcessError> {
29 if application_path.is_empty() {
30 return Err(ProcessError::EmptyPath);
31 }
32 let platform = Platform::current();
33 if platform.is_darwin() {
34 let opener = Resolver::new()
35 .lookups(["open", "/usr/bin/open"])
36 .resolve()?;
37 Command::new(opener)
38 .args(["-n", application_path])
39 .spawn()?;
40 return Ok(());
41 }
42 if platform.is_windows() {
43 Command::new("cmd")
44 .args(["/c", "start", "", application_path])
45 .spawn()?;
46 return Ok(());
47 }
48 Command::new(application_path).spawn()?;
49 Ok(())
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn requires_path() {
58 assert!(matches!(relaunch(""), Err(ProcessError::EmptyPath)));
59 }
60}