to-html 0.1.6

Render a terminal with ANSI colors as HTML
use std::{
    io::{self, Write},
    path::Path,
    process::{Child, ExitStatus},
};

use crate::StdError;

pub fn run(args: &str, shell: Option<&str>) -> Result<(String, String, ExitStatus), StdError> {
    let output =
        fake_tty::command(&format!("{}; printf \"~~////~~\"; pwd", args), shell)?.output()?;

    let stdout = fake_tty::get_stdout(output.stdout)?;
    let stderr = String::from_utf8(output.stderr)?;
    let status = output.status;

    let stdout = stdout.trim_end();
    let lb = stdout
        .rfind("~~////~~")
        .ok_or_else(|| format!("Delimiter not found in the string {:?}", stdout))
        .unwrap();

    let (output, cwd) = stdout.split_at(lb);
    let cwd = cwd.trim_start_matches("~~////~~").trim_start();

    if !cmp_paths(std::env::current_dir()?, cwd) {
        std::env::set_current_dir(cwd)?;
    }
    Ok((output.to_string(), stderr, status))
}

fn cmp_paths(p1: impl AsRef<Path>, p2: impl AsRef<Path>) -> bool {
    p1.as_ref() == p2.as_ref()
}

pub fn input(mut child: Child, input: impl AsRef<str>) -> io::Result<Child> {
    child
        .stdin
        .as_mut()
        .unwrap()
        .write_all(input.as_ref().as_bytes())?;
    Ok(child)
}

#[test]
fn test_run() {
    let (stdout, stderr, status) = run("ls -l", None).unwrap();
    assert!(
        status.success(),
        "Running `ls -l` was unsuccessful (stdout: {:?}, stderr: {:?})",
        stdout,
        stderr
    );
}