use crate::cancel::CancelToken;
use crate::engine::Engine;
use crate::executor::Executor;
use crate::span::Span;
use crate::tree::ParseTree;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Edit {
pub start: usize,
pub old_end: usize,
pub new_end: usize,
}
impl Edit {
pub fn replace(start: usize, old_end: usize, new_end: usize) -> Self {
debug_assert!(start <= old_end, "edit start must not exceed old_end");
debug_assert!(start <= new_end, "edit start must not exceed new_end");
Self {
start,
old_end,
new_end,
}
}
pub fn insert(at: usize, len: usize) -> Self {
Self::replace(at, at, at + len)
}
pub fn delete(start: usize, end: usize) -> Self {
Self::replace(start, end, start)
}
pub(crate) fn map_pos(&self, pos: usize) -> usize {
if pos <= self.start {
pos
} else if pos >= self.old_end {
self.new_end + (pos - self.old_end)
} else {
self.new_end
}
}
pub(crate) fn map_end(&self, pos: usize) -> usize {
if self.start == self.old_end {
if pos < self.start {
pos
} else {
self.new_end + (pos - self.old_end)
}
} else if pos <= self.start {
pos
} else if pos < self.old_end {
self.new_end
} else {
self.new_end + (pos - self.old_end)
}
}
pub(crate) fn touches(&self, span: &Span) -> bool {
if self.start == self.old_end {
span.start <= self.start && self.start <= span.end
} else {
span.start < self.old_end && self.start < span.end
}
}
}
pub(crate) fn map_span(span: Span, edit: &Edit, rev: u64) -> Span {
Span::new(edit.map_pos(span.start), edit.map_end(span.end), rev)
}
pub struct Session<C> {
tree: ParseTree<C>,
}
impl<C: Clone + PartialEq + Send + 'static> Session<C> {
pub fn new(source_rev: u64, root_span: Span, root_ctx: C) -> Self {
Self {
tree: ParseTree::new(source_rev, root_span, root_ctx),
}
}
pub fn from_source(source: &str, source_rev: u64, root_ctx: C) -> Self {
Self::new(source_rev, Span::new(0, source.len(), source_rev), root_ctx)
}
pub fn revision(&self) -> u64 {
self.tree.source_rev()
}
pub fn tree(&self) -> &ParseTree<C> {
&self.tree
}
pub fn tree_mut(&mut self) -> &mut ParseTree<C> {
&mut self.tree
}
pub fn edit(&mut self, edit: Edit) {
self.tree.edit(edit);
}
pub fn run<E>(
&mut self,
engine: &Engine<C>,
source: &str,
exec: &E,
cancel: &CancelToken,
) -> crate::engine::RunReport
where
E: Executor,
{
engine.run(source, &mut self.tree, exec, cancel)
}
}