pub trait Sanitizer {
fn sanitize(&self, runes: &[char]) -> Vec<char>;
}
pub fn new_sanitizer(opts: Vec<Option>) -> Sanitizer_ {
let mut s = Sanitizer_ {
replace_new_line: "\n".chars().collect(),
replace_tab: " ".chars().collect(),
};
for o in opts {
s = o(s);
}
s
}
pub type Option = Box<dyn FnOnce(Sanitizer_) -> Sanitizer_>;
pub fn replace_tabs(tab_repl: &str) -> Option {
let tab_repl = tab_repl.chars().collect();
Box::new(move |s: Sanitizer_| Sanitizer_ {
replace_tab: tab_repl,
..s
})
}
pub fn replace_newlines(nl_repl: &str) -> Option {
let nl_repl = nl_repl.chars().collect();
Box::new(move |s: Sanitizer_| Sanitizer_ {
replace_new_line: nl_repl,
..s
})
}
#[derive(Clone)]
pub struct Sanitizer_ {
replace_new_line: Vec<char>,
replace_tab: Vec<char>,
}
impl Sanitizer for Sanitizer_ {
fn sanitize(&self, runes: &[char]) -> Vec<char> {
let mut dstrunes: Vec<char> = Vec::with_capacity(runes.len());
for r in runes {
match r {
&'\u{FFFD}' => {}
&'\r' | &'\n' => {
dstrunes.extend_from_slice(&self.replace_new_line);
}
&'\t' => {
dstrunes.extend_from_slice(&self.replace_tab);
}
c if c.is_control() => {
}
_ => {
dstrunes.push(*r);
}
}
}
dstrunes
}
}