-
-
Save George-Payne/c1c56cb483459d3ce97391ce97868627 to your computer and use it in GitHub Desktop.
Book as an Iterator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Book<'a> { | |
text: &'a str, | |
width: usize, | |
} | |
impl<'a> IntoIterator for Book<'a> { | |
type Item = String; | |
type IntoIter = BookIntoIterator<'a>; | |
fn into_iter(self) -> Self::IntoIter { | |
BookIntoIterator::new(self) | |
} | |
} | |
struct BookIntoIterator<'a> { | |
words: std::str::SplitWhitespace<'a>, | |
active_word: Option<&'a str>, | |
width: usize, | |
} | |
impl<'a> BookIntoIterator<'a> { | |
pub fn new(book: Book<'a>) -> Self { | |
let mut words = book.text.split_whitespace().into_iter(); | |
let width = book.width; | |
let active_word = words.next(); | |
BookIntoIterator { | |
words, | |
width, | |
active_word, | |
} | |
} | |
} | |
impl<'a> Iterator for BookIntoIterator<'a> { | |
type Item = String; | |
fn next(&mut self) -> Option<String> { | |
let mut line = "".to_string(); | |
let mut word = match self.active_word { | |
Some(word) => word, | |
_ => return None, | |
}; | |
while line.len() + word.len() + 1 < self.width { | |
line = if line.len() > 0 { | |
[&line, word].join(" ") | |
} else { | |
word.to_string() | |
}; | |
self.active_word = self.words.next(); | |
word = match self.active_word { | |
Some(word) => word, | |
_ => break, | |
}; | |
} | |
if word.len() > self.width && self.width - line.len() > 4 { | |
let chunk_width = self.width - line.len() - 2; | |
let (head, tail) = word.split_at(chunk_width); | |
let dashed_word = [head, "-"].join(""); | |
line = if line.len() > 0 { | |
[line, dashed_word].join(" ") | |
} else { | |
dashed_word.to_string() | |
}; | |
self.active_word = Some(tail); | |
} | |
Some(line) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment