use std::{
io,
process::{Command, Stdio},
string::FromUtf8Error,
};
#[cfg(test)]
mod tests;
#[cfg(not(any(
target_os = "android",
target_os = "linux",
target_os = "macos",
target_os = "freebsd"
)))]
compile_error!("This platform is not supported. See https://github.com/Aloso/to-html/issues/3");
pub fn bash_command(command: &str) -> io::Result<Command> {
let mut command = make_script_command(command, Some("bash"))?;
command.stdout(Stdio::piped()).stderr(Stdio::piped());
Ok(command)
}
pub fn command(command: &str, shell: Option<&str>) -> io::Result<Command> {
let mut command = make_script_command(command, shell)?;
command.stdout(Stdio::piped()).stderr(Stdio::piped());
Ok(command)
}
pub fn make_script_command(c: &str, shell: Option<&str>) -> io::Result<Command> {
let shell = which_shell(shell.unwrap_or("bash"))?;
#[cfg(any(target_os = "linux", target_os = "android"))]
{
let mut command = Command::new("script");
command.args(["-qec", c, "/dev/null"]);
command.env("SHELL", shell.trim());
Ok(command)
}
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
{
let mut command = Command::new("script");
command.args(&["-q", "/dev/null", shell.trim(), "-c", c]);
Ok(command)
}
}
pub fn get_stdout(stdout: Vec<u8>) -> Result<String, FromUtf8Error> {
let out = String::from_utf8(stdout)?;
#[cfg(any(target_os = "linux", target_os = "android"))]
{
Ok(out.replace("\r\n", "\n"))
}
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
{
let mut out = out.replace("\r\n", "\n");
if out.starts_with("^D\u{8}\u{8}") {
out = out["^D\u{8}\u{8}".len()..].to_string()
}
Ok(out)
}
}
fn which_shell(shell: &str) -> io::Result<String> {
let which = Command::new("which")
.arg(shell)
.stdout(Stdio::piped())
.output()?;
if which.status.success() {
Ok(String::from_utf8(which.stdout).unwrap())
} else {
Err(io::Error::other(String::from_utf8(which.stderr).unwrap()))
}
}