use crate::event::Event;
use crate::parser::Parser;
use compactp_syntax::SyntaxKind;
use drop_bomb::DropBomb;
pub(crate) struct Marker {
pub(crate) pos: u32,
bomb: DropBomb,
}
impl Marker {
pub(crate) fn new(pos: u32) -> Self {
Self {
pos,
bomb: DropBomb::new("Marker must be either completed or abandoned"),
}
}
pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
self.bomb.defuse();
match &mut p.events[self.pos as usize] {
Event::StartNode { kind: slot, .. } => *slot = kind,
_ => unreachable!(),
}
p.push_event(Event::FinishNode);
CompletedMarker { pos: self.pos }
}
pub(crate) fn abandon(mut self, p: &mut Parser) {
self.bomb.defuse();
if self.pos as usize == p.events.len() - 1 {
match p.events.pop() {
Some(Event::StartNode {
kind: SyntaxKind::ERROR,
forward_parent: None,
}) => {
}
_ => unreachable!(),
}
} else {
p.events[self.pos as usize] = Event::Placeholder;
}
}
}
pub(crate) struct CompletedMarker {
pub(crate) pos: u32,
}
impl CompletedMarker {
pub(crate) fn precede(self, p: &mut Parser) -> Marker {
let new_m = p.start();
match &mut p.events[self.pos as usize] {
Event::StartNode { forward_parent, .. } => {
*forward_parent = Some(new_m.pos);
}
_ => unreachable!(),
}
new_m
}
}