use crate::object::Map;
pub struct Context<'a> {
pub bytes: &'a [u8],
pub routines: Vec<Routine>,
pub matched_slots: Vec<MatchRange>,
pub counter_stack: Vec<usize>,
}
pub struct Routine {
pub range_start: usize,
pub range_end: usize,
pub route_index: usize,
pub transition_stack: Vec<TransitionStackItem>,
}
impl Routine {
pub fn new(range_start: usize, range_end: usize, route_index: usize) -> Routine {
Routine {
range_start,
range_end,
route_index,
transition_stack: vec![],
}
}
}
pub struct TransitionStackItem {
pub cursor: usize,
pub repetition_count: usize,
pub current_node_index: usize,
pub transition_index: usize,
}
impl TransitionStackItem {
pub fn new(
cursor: usize,
repetition_count: usize,
current_node_index: usize,
transition_index: usize,
) -> Self {
TransitionStackItem {
cursor,
repetition_count,
current_node_index,
transition_index,
}
}
}
#[derive(Debug, PartialEq, Clone, Default)]
pub struct MatchRange {
pub start: usize,
pub end: usize,
}
impl MatchRange {
pub fn new(start: usize, end: usize) -> Self {
MatchRange { start, end }
}
}
impl<'a> Context<'a> {
pub fn new(
s: &'a str,
number_of_capture_groups: usize, ) -> Self {
let bytes = s.as_bytes();
Self::from_bytes(bytes, number_of_capture_groups)
}
pub fn from_bytes(
bytes: &'a [u8],
number_of_capture_groups: usize, ) -> Self {
Context {
bytes,
routines: vec![],
counter_stack: vec![],
matched_slots: vec![MatchRange::default(); number_of_capture_groups],
}
}
pub fn push_transitions_of_node(
&mut self,
map: &Map,
node_index: usize,
cursor: usize,
repetition_count: usize,
) {
let routine = self.get_current_routine_ref_mut();
let route_index = routine.route_index;
let node = &map.routes[route_index].nodes[node_index];
let transition_count = node.path.len();
for transition_index in (0..transition_count).rev() {
routine.transition_stack.push(TransitionStackItem::new(
cursor,
repetition_count,
node_index,
transition_index,
));
}
}
pub fn pop_transition_stack_item(&mut self) -> Option<TransitionStackItem> {
self.get_current_routine_ref_mut().transition_stack.pop()
}
#[inline]
pub fn get_current_routine_ref(&self) -> &Routine {
self.routines.last().unwrap()
}
#[inline]
pub fn get_current_routine_ref_mut(&mut self) -> &mut Routine {
let count = self.routines.len();
&mut self.routines[count - 1]
}
}