use std::path::PathBuf;
use std::process::{Child, Command};
use super::*;
pub trait WineRunExt {
fn run<T: AsRef<OsStr>>(&self, binary: T) -> Result<Child>;
fn run_args<T, S>(&self, args: T) -> Result<Child>
where
T: IntoIterator<Item = S>,
S: AsRef<OsStr>;
fn run_args_with_env<T, K, S>(&self, args: T, envs: K) -> Result<Child>
where
T: IntoIterator<Item = S>,
K: IntoIterator<Item = (S, S)>,
S: AsRef<OsStr>;
fn winepath(&self, path: &str) -> Result<PathBuf>;
}
impl WineRunExt for Wine {
fn run<T: AsRef<OsStr>>(&self, binary: T) -> Result<Child> {
self.run_args_with_env([binary], [])
}
fn run_args<T, S>(&self, args: T) -> Result<Child>
where
T: IntoIterator<Item = S>,
S: AsRef<OsStr>
{
self.run_args_with_env(args, [])
}
fn run_args_with_env<T, K, S>(&self, args: T, envs: K) -> Result<Child>
where
T: IntoIterator<Item = S>,
K: IntoIterator<Item = (S, S)>,
S: AsRef<OsStr>
{
let mut command = Command::new(&self.binary);
command
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped());
if let Some(prefix) = &self.prefix {
command.env("WINEPREFIX", prefix);
}
if let Some(arch) = self.arch {
command.env("WINEARCH", arch.to_str());
}
if let Some(server) = &self.wineserver {
command.env("WINESERVER", server);
}
match &self.wineloader {
WineLoader::Default => (),
WineLoader::Current => {
command.env("WINELOADER", &self.binary);
},
WineLoader::Custom(path) => {
command.env("WINELOADER", path);
}
}
command.envs(envs).spawn()
}
fn winepath(&self, path: &str) -> Result<PathBuf> {
let output = self.run_args(["winepath", "-u", path])?.wait_with_output()?;
match output.status.success() {
true => {
let path = PathBuf::from(OsString::from_vec(output.stdout[..output.stdout.len() - 1].to_vec()));
match path.exists() {
true => Ok(path),
false => Err(Error::new(ErrorKind::Other, "Wine path is not correct: ".to_string() + &String::from_utf8_lossy(&output.stdout)))
}
}
false => Err(Error::new(ErrorKind::Other, "Failed to find wine path: ".to_string() + &String::from_utf8_lossy(&output.stdout)))
}
}
}