1#![allow(clippy::literal_string_with_formatting_args)]
5
6pub mod backend;
8
9use aho_corasick::{AhoCorasick, PatternID};
10use std::{error::Error, ffi::OsStr};
11use tempfile::NamedTempFile;
12
13pub type TestResult<T> = Result<T, Box<dyn Error>>;
15
16pub fn get_matches<I, P>(patterns: I, output: &str) -> TestResult<Vec<(PatternID, usize)>>
31where
32 I: IntoIterator<Item = P>,
33 P: AsRef<[u8]>,
34{
35 let ac = AhoCorasick::new(patterns)?;
36 let mut matches = vec![];
37 for mat in ac.find_iter(output) {
38 add_match_to_vector(&mut matches, mat);
39 }
40 Ok(matches)
41}
42
43pub fn add_match_to_vector(matches: &mut Vec<(PatternID, usize)>, mat: aho_corasick::Match) {
50 matches.push((mat.pattern(), mat.end() - mat.start()));
51}
52
53pub fn get_temp_file() -> TestResult<NamedTempFile> {
63 Ok(NamedTempFile::new()?)
64}
65
66pub fn files_differ(
81 path_left: impl AsRef<OsStr>,
82 path_right: impl AsRef<OsStr>,
83) -> TestResult<bool> {
84 #[cfg(not(windows))]
86 {
87 let proc = std::process::Command::new("diff")
88 .arg(path_left)
89 .arg(path_right)
90 .output()?;
91
92 if proc.stdout.is_empty() {
93 return Ok(false);
94 }
95 }
96
97 #[cfg(windows)]
98 {
99 let proc = std::process::Command::new("fc.exe")
100 .arg("/L")
101 .arg(path_left)
102 .arg(path_right)
103 .output()?;
104
105 let output = String::from_utf8(proc.stdout)?;
106
107 dbg!(&output);
108
109 let patterns = &["FC: no differences encountered"];
110 let ac = AhoCorasick::new(patterns)?;
111 let mut matches = vec![];
112
113 for mat in ac.find_iter(output.as_str()) {
114 matches.push((mat.pattern(), mat.end() - mat.start()));
115 }
116
117 if matches == vec![(PatternID::must(0), 30)] {
118 return Ok(false);
119 }
120 }
121
122 Ok(true)
123}