use regex::{Regex, RegexBuilder};
lazy_static! {
static ref WHITESPACE: Regex = {
RegexBuilder::new(r"^\s+$")
.multi_line(true)
.build()
.unwrap()
};
static ref LEADING_NEWLINES: Regex = Regex::new(r"^\n+").unwrap();
static ref TRAILING_NEWLINES: Regex = Regex::new(r"\n+$").unwrap();
}
pub fn substitute(log: &slog::Logger, text: &mut String) {
str_replace(log, text, "\r\n", "\n");
str_replace(log, text, "\r", "\n");
regex_replace(log, text, &*WHITESPACE, "");
str_replace(log, text, "\\\n", "");
str_replace(log, text, "\t", " ");
regex_replace(log, text, &*LEADING_NEWLINES, "");
regex_replace(log, text, &*TRAILING_NEWLINES, "");
}
fn str_replace(log: &slog::Logger, text: &mut String, pattern: &str, replacement: &str) {
debug!(
log,
"Replacing miscellaneous static string";
"type" => "string",
"text" => &*text,
"pattern" => pattern,
"replacement" => replacement,
);
while let Some(idx) = text.find(pattern) {
let range = idx..idx + pattern.len();
text.replace_range(range, replacement);
}
}
fn regex_replace(
log: &slog::Logger,
text: &mut String,
regex: &Regex,
replacement: &str,
) {
debug!(
log,
"Replacing miscellaneous regular expression";
"type" => "regex",
"text" => &*text,
"pattern" => regex.as_str(),
"replacement" => replacement,
);
while let Some(mtch) = regex.find(text) {
let range = mtch.start()..mtch.end();
text.replace_range(range, replacement);
}
}
#[cfg(test)]
const TEST_CASES: [(&str, &str); 6] = [
(
"\tapple\n\tbanana\tcherry\n",
" apple\n banana cherry",
),
(
"newlines:\r\n* apple\r* banana\r\ncherry\n\r* durian",
"newlines:\n* apple\n* banana\ncherry\n\n* durian",
),
(
"apple\nbanana\n\ncherry\n\n\npineapple\n\n\n\nstrawberry\n\n\n\n\nblueberry\n\n\n\n\n\n",
"apple\nbanana\n\ncherry\n\npineapple\n\nstrawberry\n\nblueberry",
),
(
"apple\rbanana\r\rcherry\r\r\rpineapple\r\r\r\rstrawberry\r\r\r\r\rblueberry\r\r\r\r\r\r",
"apple\nbanana\n\ncherry\n\npineapple\n\nstrawberry\n\nblueberry",
),
(
"concat:\napple banana \\\nCherry\\\nPineapple \\ grape\nblueberry\n",
"concat:\napple banana CherryPineapple \\ grape\nblueberry",
),
("<\n \n \n \n \n>", "<\n\n>"),
];
#[test]
fn regexes() {
let _ = &*WHITESPACE;
}
#[test]
fn test_substitute() {
use super::test::test_substitution;
test_substitution("miscellaneous", substitute, &TEST_CASES);
}