word_cloud/words/
default_word_provider.rs

1use std::collections::HashMap;
2
3use crate::{
4    colors::ColorProvider,
5    words::{FontProvider, FontSizeProvider, Word, WordsProvider},
6};
7
8pub struct DefaultWordProvider {
9    words: Vec<Word>,
10    cur_word: usize,
11}
12
13impl WordsProvider for DefaultWordProvider {
14    fn get_next_word(&mut self) -> Option<Word> {
15        if self.cur_word >= self.words.len() - 1 {
16            return None;
17        }
18
19        self.cur_word += 1;
20
21        Some(self.words[self.cur_word].clone())
22    }
23}
24
25impl DefaultWordProvider {
26    pub fn new<FSP, CP>(
27        text: &str,
28        font_size_provider: FSP,
29        color_provider: &mut CP,
30        fonts_provider: &FontProvider,
31    ) -> DefaultWordProvider
32    where
33        FSP: FontSizeProvider,
34        CP: ColorProvider,
35    {
36        let words: Vec<String> = text
37            .replace(['.', ',', ';'], "")
38            .split(' ')
39            .map(|w| w.to_lowercase())
40            .filter(|w| w.len() > 3)
41            .collect();
42
43        // TODO - filter
44
45        let mut buffer: HashMap<String, Word> = HashMap::new();
46
47        for text in words {
48            if buffer.contains_key(&text) {
49                let mut w = buffer.get(&text).unwrap().clone();
50                w.count += 1;
51                w.size = font_size_provider.get_font_size(&w);
52
53                buffer.remove(&text);
54                buffer.insert(text, w);
55            } else {
56                let mut word = Word::new(
57                    &text,
58                    crate::geometry::Orientation::random(),
59                    color_provider.random_color(),
60                    &fonts_provider.random_font_name(),
61                    0,
62                );
63
64                word.size = font_size_provider.get_font_size(&word);
65
66                buffer.insert(text, word);
67            }
68        }
69
70        // Insert the biggest words first
71        let mut list: Vec<Word> = buffer.into_values().collect();
72        list.sort_by(|a, b| a.size.cmp(&b.size));
73        list.reverse();
74
75        DefaultWordProvider {
76            words: list,
77            cur_word: 0,
78        }
79    }
80}