pub(crate) fn pretty_pattern(pretty_dbg: &str) -> String {
pretty_dbg
.split('\n')
.map(|line| format!(" *{}", regex::escape(line)))
.collect::<Vec<_>>()
.join("\n")
}
pub(crate) fn combined_pretty_regex(patterns: &[String]) -> regex::Regex {
let alternation = patterns
.iter()
.map(|p| format!("({p})"))
.collect::<Vec<_>>()
.join("|");
regex::Regex::new(&alternation).expect("pretty patterns are always valid regexes")
}
pub(crate) fn pretty_replace_all(
regex: ®ex::Regex,
text: &str,
replacements: &[String],
) -> String {
regex
.replace_all(text, PrettyReplacer(replacements))
.to_string()
}
struct PrettyReplacer<'a>(&'a [String]);
impl<'a> regex::Replacer for PrettyReplacer<'a> {
fn replace_append(&mut self, caps: ®ex::Captures<'_>, dst: &mut String) {
let matched = caps.get(0).expect("a match always has group 0").as_str();
let idx = (1..caps.len())
.find(|&i| caps.get(i).is_some())
.expect("exactly one alternative matches")
- 1;
let spaces: String = matched.chars().take_while(|c| c.is_whitespace()).collect();
let replaced = self.0[idx]
.split('\n')
.map(|line| format!("{spaces}{line}"))
.collect::<Vec<_>>()
.join("\n");
dst.push_str(&replaced);
}
}