| 1 | //! Datastructures and operations used for normalizing test output. |
|---|---|
| 2 | |
| 3 | use crate::display; |
| 4 | use bstr::ByteSlice; |
| 5 | use regex::bytes::{Captures, Regex}; |
| 6 | use std::borrow::Cow; |
| 7 | use std::path::Path; |
| 8 | use std::sync::OnceLock; |
| 9 | |
| 10 | /// A filter's match rule. |
| 11 | #[derive(Clone, Debug)] |
| 12 | pub enum Match { |
| 13 | /// If the regex matches, the filter applies |
| 14 | Regex(Regex), |
| 15 | /// If the exact byte sequence is found, the filter applies |
| 16 | Exact(Vec<u8>), |
| 17 | /// Uses a heuristic to find backslashes in windows style paths |
| 18 | PathBackslash, |
| 19 | } |
| 20 | |
| 21 | impl Match { |
| 22 | pub(crate) fn replace_all<'a>(&self, text: &'a [u8], replacement: &[u8]) -> Cow<'a, [u8]> { |
| 23 | match self { |
| 24 | Match::Regex(regex) => regex.replace_all(text, replacement), |
| 25 | Match::Exact(needle) => text.replace(needle, replacement).into(), |
| 26 | Match::PathBackslash => { |
| 27 | static PATH_RE: OnceLock<Regex> = OnceLock::new(); |
| 28 | PATH_RE |
| 29 | .get_or_init(|| { |
| 30 | Regex::new( |
| 31 | r"(?x) |
| 32 | (?: |
| 33 | # Match paths to files with extensions that don't include spaces |
| 34 | \\(?:[\pL\pN.\-_']+[/\\])*[\pL\pN.\-_']+\.\pL+ |
| 35 | | |
| 36 | # Allow spaces in absolute paths |
| 37 | [A-Z]:\\(?:[\pL\pN.\-_'\ ]+[/\\])+ |
| 38 | )", |
| 39 | ) |
| 40 | .unwrap() |
| 41 | }) |
| 42 | .replace_all(text, |caps: &Captures<'_>| { |
| 43 | caps[0].replace(r"\", replacement) |
| 44 | }) |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | impl From<&'_ Path> for Match { |
| 51 | fn from(v: &Path) -> Self { |
| 52 | let mut v: String = display(path:v); |
| 53 | // Normalize away windows canonicalized paths. |
| 54 | if v.starts_with(r"//?/") { |
| 55 | v.drain(range:0..4); |
| 56 | } |
| 57 | Self::Exact(v.into_bytes()) |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | impl From<Regex> for Match { |
| 62 | fn from(v: Regex) -> Self { |
| 63 | Self::Regex(v) |
| 64 | } |
| 65 | } |
| 66 |
