use crate::{Cursor, CursorSink, Kind};
pub struct CursorInterleaveSink<'a, S> {
sink: &'a mut S,
interleave: &'a [(bumpalo::collections::Vec<'a, Cursor>, Cursor)],
current_index: usize,
#[cfg(debug_assertions)]
seen_eof: bool,
}
impl<'a, S: CursorSink> CursorInterleaveSink<'a, S> {
pub fn new(sink: &'a mut S, interleave: &'a [(bumpalo::collections::Vec<'a, Cursor>, Cursor)]) -> Self {
Self {
sink,
interleave,
current_index: 0,
#[cfg(debug_assertions)]
seen_eof: false,
}
}
}
impl<'a, S: CursorSink> CursorSink for CursorInterleaveSink<'a, S> {
fn append(&mut self, c: Cursor) {
#[cfg(debug_assertions)]
{
debug_assert!(!self.seen_eof, "Received cursor after EOF: {:?}", c);
if c == Kind::Eof {
self.seen_eof = true;
}
}
while self.current_index < self.interleave.len() {
let (trivia, associated_cursor) = &self.interleave[self.current_index];
if *associated_cursor == c {
for cursor in trivia {
self.sink.append(*cursor);
}
self.current_index += 1;
break;
}
if associated_cursor.span().start() > c.span().start() {
break;
}
self.current_index += 1;
}
if c == Kind::Eof {
while self.current_index < self.interleave.len() {
let (trivia, _) = &self.interleave[self.current_index];
for cursor in trivia {
self.sink.append(*cursor);
}
self.current_index += 1;
}
}
self.sink.append(c);
}
}