string_sections/
section_iter.rs1use std::{iter::FusedIterator, str::Lines};
2
3use crate::{section_span::SectionSpan, SectionFinder};
4
5pub use super::LineSpan;
6
7#[derive(Clone)]
8pub struct SectionIter<'a, F: SectionFinder> {
9 pub(crate) text: &'a str,
10 pub(crate) iter: Lines<'a>,
11 pub(crate) finder: F,
12}
13
14impl<'a, F: SectionFinder> SectionIter<'a, F> {
15 fn next_start(&mut self) -> Option<LineSpan<'a>> {
16 while let Some(line) = self.iter.next() {
17 let line = LineSpan::new(self.text, line);
18
19 if self.finder.is_start(&line) {
20 return Some(line);
21 }
22 }
23 None
24 }
25
26 fn forward_to_end(&mut self, section: &mut SectionSpan<'a>) -> bool {
27 while let Some(line) = self.iter.next() {
28 section.end_line = LineSpan::new(self.text, line);
29 if self.finder.is_end(§ion) {
30 return true;
31 }
32 }
33 false
34 }
35}
36
37impl<'a, F: SectionFinder> Iterator for SectionIter<'a, F> {
38 type Item = SectionSpan<'a>;
39
40 fn next(&mut self) -> Option<Self::Item> {
41 if let Some(start_line) = self.next_start() {
42 let mut section = SectionSpan {
43 start_line,
44 end_line: start_line,
45 };
46 self.forward_to_end(&mut section);
47 Some(section)
48 } else {
49 None
50 }
51 }
52}
53
54impl<'a, F: SectionFinder> FusedIterator for SectionIter<'a, F> {}