perl_module/boundary/
mod.rs1use crate::token_core::has_standalone_module_token_boundaries;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct ModuleTokenRange {
12 pub start: usize,
14 pub end: usize,
16}
17
18#[derive(Debug, Clone)]
20pub struct ModuleTokenRangeIter<'a> {
21 line: &'a str,
22 module_name: &'a str,
23 search_start: usize,
24 done: bool,
25}
26
27impl<'a> Iterator for ModuleTokenRangeIter<'a> {
28 type Item = ModuleTokenRange;
29
30 fn next(&mut self) -> Option<Self::Item> {
31 if self.done || self.module_name.is_empty() || self.line.is_empty() {
32 self.done = true;
33 return None;
34 }
35
36 while self.search_start <= self.line.len() {
37 let Some(rel_pos) = self.line[self.search_start..].find(self.module_name) else {
38 break;
39 };
40
41 let start = self.search_start + rel_pos;
42 let end = start + self.module_name.len();
43 self.search_start = end;
44
45 if has_standalone_module_token_boundaries(self.line, start, end) {
46 return Some(ModuleTokenRange { start, end });
47 }
48 }
49
50 self.done = true;
51 None
52 }
53}
54
55#[must_use]
57pub fn find_standalone_module_token_ranges<'a>(
58 line: &'a str,
59 module_name: &'a str,
60) -> ModuleTokenRangeIter<'a> {
61 ModuleTokenRangeIter { line, module_name, search_start: 0, done: false }
62}
63
64#[must_use]
66pub fn contains_standalone_module_token(line: &str, module_name: &str) -> bool {
67 find_standalone_module_token_ranges(line, module_name).next().is_some()
68}