use super::Substitutor;
use super::SubstitutorAddError;
use std::borrow::Cow;
#[derive(Clone, Debug)]
struct Replacer {
matcher: regex::Regex,
replace: String,
limit: usize,
}
impl Replacer {
fn new(pattern: &str, repl: String, limit: usize) -> Result<Self, SubstitutorAddError> {
match regex::Regex::new(pattern) {
Err(e) => {
let err_msg = match e {
regex::Error::Syntax(s) => s,
regex::Error::CompiledTooBig(_) => "Compiled Too Big".to_string(),
_ => "Unknown Error".to_string(),
};
Result::Err(SubstitutorAddError::new(err_msg))
}
Ok(re) => Ok(Self {
matcher: re,
replace: repl,
limit,
}),
}
}
fn replace<'a>(&self, s: &'a Cow<'a, str>) -> Cow<'a, str> {
self.matcher.replacen(s, self.limit, &self.replace)
}
}
#[derive(Clone, Debug)]
pub struct RegexGsub {
params: Vec<Replacer>,
}
impl Substitutor for RegexGsub {
fn new() -> Self {
Self { params: Vec::new() }
}
fn gsub<'a>(&self, s: &'a str) -> Cow<'a, str> {
let mut r = Cow::from(s);
for param in self.params.iter() {
if let Cow::Owned(s2) = param.replace(&r) {
*r.to_mut() = s2;
}
}
r
}
fn add(
&mut self,
pattern: &str,
repl: String,
limit: usize,
) -> Result<(), SubstitutorAddError> {
let r = Replacer::new(pattern, repl, limit)?;
self.params.push(r);
Result::Ok(())
}
}