use super::{Captures, Regex};
use std::borrow::Cow;
pub trait Replacer {
fn reg_replace(&mut self, caps: &Captures) -> Cow<str>;
}
impl<'t> Replacer for &'t str {
fn reg_replace(&mut self, _: &Captures) -> Cow<str> {
(*self).into()
}
}
impl<F> Replacer for F
where
F: FnMut(&Captures) -> String,
{
fn reg_replace<'a>(&'a mut self, caps: &Captures) -> Cow<'a, str> {
(*self)(caps).into()
}
}
impl Regex {
pub fn replace<R: Replacer>(&self, text: &str, rep: R) -> String {
self.replacen(text, 1, rep)
}
pub fn replace_all<R: Replacer>(&self, text: &str, rep: R) -> String {
self.replacen(text, 0, rep)
}
pub fn replacen<R: Replacer>(&self, text: &str, limit: usize, mut rep: R) -> String {
let mut new = String::with_capacity(text.len());
let mut last_match = 0;
for (i, cap) in self.captures_iter(text).enumerate() {
if limit > 0 && i >= limit {
break;
}
let (s, e) = cap.pos(0).unwrap();
new.push_str(&text[last_match..s]);
new.push_str(&rep.reg_replace(&cap));
last_match = e;
}
new.push_str(&text[last_match..]);
new
}
}