use pretty_assertions::assert_eq as pretty_assert_eq;
use std::path::Path;
use std::process::Command;
pub fn assert_matches_expected(
base: &Path,
actual: &Path,
expected: &Path,
) -> Result<(), anyhow::Error> {
assert_eq!(
actual.is_file(),
expected.is_file(),
"actual '{}' is_file({}) != expected '{}' is_file({})",
actual.display(),
actual.is_file(),
expected.display(),
expected.is_file()
);
if actual.is_file() {
let actual_content = std::fs::read_to_string(actual)?;
let expected_content = std::fs::read_to_string(expected)?;
pretty_assert_eq!(
PrettyString(&actual_content),
PrettyString(&expected_content),
"contents of actual file '{}' differs from the contents of expected file '{}'",
actual.strip_prefix(base)?.display(),
expected.strip_prefix(base)?.display()
);
} else {
let mut expected_it = std::fs::read_dir(expected)?;
while let Some(expected_child) = expected_it.next() {
let expected_child = expected_child?;
let name = expected_child.file_name();
let actual_child = actual.join(&name);
assert!(
actual_child.exists(),
"expected file '{}' does not exists in actual output '{}'",
Path::new(&name).display(),
actual.strip_prefix(base)?.display()
);
assert_matches_expected(base, &actual_child, &expected_child.path())?;
}
let mut actual_it = std::fs::read_dir(actual)?;
while let Some(actual_child) = actual_it.next() {
let actual_child = actual_child?;
let name = actual_child.file_name();
let expected_child = expected.join(&name);
if name != "Cargo.lock" {
assert!(
expected_child.exists(),
"actual file '{}' does not exists in expected output '{}'",
Path::new(&name).display(),
actual.strip_prefix(base)?.display()
);
}
}
}
Ok(())
}
#[derive(PartialEq, Eq)]
#[doc(hidden)]
pub struct PrettyString<'a>(pub &'a str);
impl<'a> std::fmt::Debug for PrettyString<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.write_str(self.0)
}
}
pub fn install_rustfmt(path: &Path) -> Result<(), anyhow::Error> {
let output = Command::new("rustup")
.arg("component")
.arg("add")
.arg("rustfmt")
.current_dir(path.canonicalize()?)
.output()?;
if !output.status.success() {
let err = String::from_utf8(output.stderr)?;
eprintln!(
"Warning: failed to install rust fmt (exit code {}): {}",
output.status.code().unwrap_or(0),
err
);
}
Ok(())
}