use crate::{Rewriter, Writer};
use pulldown_cmark::Event;
pub fn rewrite<'src, E, R>(
events: E,
rewriter: R,
) -> impl Iterator<Item = Event<'src>> + 'src
where
E: IntoIterator<Item = Event<'src>>,
E::IntoIter: 'src,
R: Rewriter<'src> + 'src,
{
Rewritten::new(events.into_iter(), rewriter)
}
#[derive(Debug)]
pub struct Rewritten<'src, E, R> {
events: E,
rewriter: R,
writer: Writer<'src>,
}
impl<'src, E, R> Rewritten<'src, E, R> {
pub fn new(events: E, rewriter: R) -> Self {
Rewritten {
rewriter,
events,
writer: Writer::new(),
}
}
}
impl<'src, E, R> Iterator for Rewritten<'src, E, R>
where
E: Iterator<Item = Event<'src>>,
R: Rewriter<'src>,
{
type Item = Event<'src>;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(ev) = self.writer.buffer.pop_front() {
return Some(ev);
}
let event = self.events.next()?;
self.rewriter.rewrite_event(event, &mut self.writer);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use pulldown_cmark::Tag;
#[test]
fn ignore_some_events() {
let events = vec![
Event::Start(Tag::Paragraph),
Event::Text("This is some text.".into()),
Event::Start(Tag::Heading(2)),
Event::Text("This is some more text.".into()),
];
let rewritten: Vec<Event<'static>> = rewrite(
events,
|event: Event<'static>, writer: &mut Writer<'static>| {
if let event @ Event::Text(_) = event {
writer.push(event);
}
},
)
.collect();
assert_eq!(
rewritten,
vec![
Event::Text("This is some text.".into()),
Event::Text("This is some more text.".into()),
]
);
}
}