use std::collections::HashMap;
use crate::{
colors::ColorProvider,
words::{FontProvider, FontSizeProvider, Word, WordsProvider},
};
pub struct DefaultWordProvider {
words: Vec<Word>,
cur_word: usize,
}
impl WordsProvider for DefaultWordProvider {
fn get_next_word(&mut self) -> Option<Word> {
if self.cur_word >= self.words.len() - 1 {
return None;
}
self.cur_word += 1;
Some(self.words[self.cur_word].clone())
}
}
impl DefaultWordProvider {
pub fn new<FSP, CP>(
text: &str,
font_size_provider: FSP,
color_provider: &mut CP,
fonts_provider: &FontProvider,
) -> DefaultWordProvider
where
FSP: FontSizeProvider,
CP: ColorProvider,
{
let words: Vec<String> = text
.replace(['.', ',', ';'], "")
.split(' ')
.map(|w| w.to_lowercase())
.filter(|w| w.len() > 3)
.collect();
let mut buffer: HashMap<String, Word> = HashMap::new();
for text in words {
if buffer.contains_key(&text) {
let mut w = buffer.get(&text).unwrap().clone();
w.count += 1;
w.size = font_size_provider.get_font_size(&w);
buffer.remove(&text);
buffer.insert(text, w);
} else {
let mut word = Word::new(
&text,
crate::geometry::Orientation::random(),
color_provider.random_color(),
&fonts_provider.random_font_name(),
0,
);
word.size = font_size_provider.get_font_size(&word);
buffer.insert(text, word);
}
}
let mut list: Vec<Word> = buffer.into_values().collect();
list.sort_by(|a, b| a.size.cmp(&b.size));
list.reverse();
DefaultWordProvider {
words: list,
cur_word: 0,
}
}
}