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