use std::path::PathBuf;
use std::process::{Child, Command};
use std::ffi::OsStr;
use crate::wine::*;
pub trait WineRunExt {
fn run<T: AsRef<OsStr>>(&self, binary: T) -> anyhow::Result<Child>;
fn run_args<T, S>(&self, args: T) -> anyhow::Result<Child>
where
T: IntoIterator<Item = S>,
S: AsRef<OsStr>;
fn run_args_with_env<T, K, S>(&self, args: T, envs: K) -> anyhow::Result<Child>
where
T: IntoIterator<Item = S>,
K: IntoIterator<Item = (S, S)>,
S: AsRef<OsStr>;
fn winepath(&self, path: &str) -> anyhow::Result<PathBuf>;
}
impl WineRunExt for Wine {
#[inline]
fn run<T: AsRef<OsStr>>(&self, binary: T) -> anyhow::Result<Child> {
self.run_args_with_env([binary], [])
}
#[inline]
fn run_args<T, S>(&self, args: T) -> anyhow::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) -> anyhow::Result<Child>
where
T: IntoIterator<Item = S>,
K: IntoIterator<Item = (S, S)>,
S: AsRef<OsStr>
{
Ok(Command::new(&self.binary)
.args(args)
.envs(self.get_envs())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.envs(envs)
.spawn()?)
}
fn winepath(&self, path: &str) -> anyhow::Result<PathBuf> {
let output = self.run_args(["winepath", "-u", path])?.wait_with_output()?;
let true = output.status.success() else {
anyhow::bail!("Failed to find wine path: {}", String::from_utf8_lossy(&output.stdout));
};
let path = PathBuf::from(OsString::from_vec(output.stdout[..output.stdout.len() - 1].to_vec()));
if !path.exists() {
anyhow::bail!("Wine path is not correct: {}", String::from_utf8_lossy(&output.stdout));
}
Ok(path)
}
}