use crate::token_core::has_standalone_module_token_boundaries;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ModuleTokenRange {
pub start: usize,
pub end: usize,
}
#[derive(Debug, Clone)]
pub struct ModuleTokenRangeIter<'a> {
line: &'a str,
module_name: &'a str,
search_start: usize,
done: bool,
}
impl<'a> Iterator for ModuleTokenRangeIter<'a> {
type Item = ModuleTokenRange;
fn next(&mut self) -> Option<Self::Item> {
if self.done || self.module_name.is_empty() || self.line.is_empty() {
self.done = true;
return None;
}
while self.search_start <= self.line.len() {
let Some(rel_pos) = self.line[self.search_start..].find(self.module_name) else {
break;
};
let start = self.search_start + rel_pos;
let end = start + self.module_name.len();
self.search_start = end;
if has_standalone_module_token_boundaries(self.line, start, end) {
return Some(ModuleTokenRange { start, end });
}
}
self.done = true;
None
}
}
#[must_use]
pub fn find_standalone_module_token_ranges<'a>(
line: &'a str,
module_name: &'a str,
) -> ModuleTokenRangeIter<'a> {
ModuleTokenRangeIter { line, module_name, search_start: 0, done: false }
}
#[must_use]
pub fn contains_standalone_module_token(line: &str, module_name: &str) -> bool {
find_standalone_module_token_ranges(line, module_name).next().is_some()
}