ptero/
text.rs

1/// Cover text iterator which traverses the text word by word.
2/// It also enables the user to peek the word without forwarding the iterator.
3#[derive(Debug)]
4pub struct CoverTextWordIterator {
5    words: Vec<String>,
6    word_index: usize,
7}
8
9/// Cover text iterator which traverses the text line by line.
10#[derive(Debug)]
11pub struct CoverTextLineIterator {
12    lines: Vec<String>,
13    line_index: usize,
14}
15
16impl CoverTextWordIterator {
17    pub fn new(cover_text: &str) -> Self {
18        CoverTextWordIterator {
19            words: cover_text
20                .split_whitespace()
21                .collect::<Vec<&str>>()
22                .iter()
23                .map(|v| v.to_string())
24                .collect(),
25            word_index: 0,
26        }
27    }
28
29    /// # Examples
30    ///
31    /// ## Returns the next word without forwarding the iterator
32    /// ```
33    /// use ptero::text::CoverTextWordIterator;
34    ///
35    /// let text = "a b c d e;";
36    /// let iter: CoverTextWordIterator = CoverTextWordIterator::new(&text);
37    ///
38    /// assert_eq!(iter.peek(), Some("a".to_owned()));
39    /// assert_eq!(iter.peek(), Some("a".to_owned()));
40    /// ```
41    pub fn peek(&self) -> Option<String> {
42        self.words
43            .get(self.word_index)
44            .map(|string| string.to_owned())
45    }
46}
47
48impl Iterator for CoverTextWordIterator {
49    type Item = String;
50
51    /// # Examples
52    ///
53    /// ## Returns the next word
54    /// ```
55    /// use ptero::text::CoverTextWordIterator;
56    ///
57    /// let text = "a b c";
58    /// let mut iter: CoverTextWordIterator = CoverTextWordIterator::new(&text);
59    ///
60    /// assert_eq!(iter.next(), Some("a".to_owned()));
61    /// assert_eq!(iter.next(), Some("b".to_owned()));
62    /// ```
63    /// ## Returns `None` when iterator has traversed all the words and does not repeat
64    /// ```
65    /// use ptero::text::CoverTextWordIterator;
66    ///
67    /// let text = "a b c";
68    /// let mut iter: CoverTextWordIterator = CoverTextWordIterator::new(&text);
69    ///
70    /// assert_eq!(iter.next(), Some("a".to_owned()));
71    /// assert_eq!(iter.next(), Some("b".to_owned()));
72    /// assert_eq!(iter.next(), Some("c".to_owned()));
73    /// assert_eq!(iter.next(), None);
74    /// assert_eq!(iter.next(), None);
75    /// ```
76    fn next(&mut self) -> Option<Self::Item> {
77        let word = self.peek()?;
78        self.word_index += 1;
79        Some(word)
80    }
81}
82
83impl CoverTextLineIterator {
84    pub fn new(cover_text: &str) -> Self {
85        CoverTextLineIterator {
86            lines: cover_text
87                .lines()
88                .map(|v| v.to_string())
89                .collect::<Vec<String>>(),
90            line_index: 0,
91        }
92    }
93}
94
95impl Iterator for CoverTextLineIterator {
96    type Item = String;
97
98    /// # Examples
99    ///
100    /// ## Returns the next line
101    /// ```
102    /// use ptero::text::CoverTextLineIterator;
103    ///
104    /// let text = "a b c";
105    /// let mut iter: CoverTextLineIterator = CoverTextLineIterator::new(&text);
106    ///
107    /// assert_eq!(iter.next(), Some("a b c".to_owned()));
108    /// ```
109    /// ## Returns `None` when traversed all the lines and does not repeat
110    /// ```
111    /// use ptero::text::CoverTextLineIterator;
112    ///
113    /// let text = "a b c\na";
114    /// let mut iter: CoverTextLineIterator = CoverTextLineIterator::new(&text);
115    ///
116    /// assert_eq!(iter.next(), Some("a b c".to_owned()));
117    /// assert_eq!(iter.next(), Some("a".to_owned()));
118    /// assert_eq!(iter.next(), None);
119    /// assert_eq!(iter.next(), None);
120    /// ```
121    fn next(&mut self) -> Option<Self::Item> {
122        let line = self.lines.get(self.line_index).map(|x| x.to_owned())?;
123        self.line_index += 1;
124        Some(line)
125    }
126}