flesh_reading_ease/
lib.rs

1use regex::Regex;
2
3pub enum Language {
4    English,
5    French,
6    German,
7    Dutch,
8    Polish,
9    Bulgarian,
10}
11
12pub struct FleschReadingEase {
13    language: Language,
14}
15
16impl FleschReadingEase {
17    pub fn new(language: Language) -> Self {
18        FleschReadingEase { language }
19    }
20
21    pub fn calculate(&self, text: &str) -> f64 {
22        let sentence_count = self.count_sentences(text);
23        let word_count = self.count_words(text);
24        let syllable_count = self.count_syllables(text);
25
26        if sentence_count == 0 || word_count == 0 {
27            return 0.0;
28        }
29
30        let score = match self.language {
31            Language::English => {
32                206.835 - 1.015 * (word_count as f64 / sentence_count as f64) - 84.6 * (syllable_count as f64 / word_count as f64)
33            },
34            Language::French => {
35                207.0 - 1.015 * (word_count as f64 / sentence_count as f64) - 73.6 * (syllable_count as f64 / word_count as f64)
36            },
37            Language::German => {
38                180.0 - (word_count as f64 / sentence_count as f64) - 58.5 * (syllable_count as f64 / word_count as f64)
39            },
40            Language::Dutch => {
41                206.835 - 0.93 * (word_count as f64 / sentence_count as f64) - 77.0 * (syllable_count as f64 / word_count as f64)
42            },
43            Language::Polish => {
44                206.835 - 1.3 * (word_count as f64 / sentence_count as f64) - 85.6 * (syllable_count as f64 / word_count as f64)
45            },
46            Language::Bulgarian => {
47                206.835 - 1.5 * (word_count as f64 / sentence_count as f64) - 60.0 * (syllable_count as f64 / word_count as f64)
48            },
49        };
50
51        score.clamp(0.0, 100.0)
52    }
53
54    fn count_sentences(&self, text: &str) -> usize {
55        let re = Regex::new(r"[.!?]").unwrap();
56        re.find_iter(text).count()
57    }
58
59    fn count_words(&self, text: &str) -> usize {
60        let re = Regex::new(r"\w+").unwrap();
61        re.find_iter(text).count()
62    }
63
64    fn count_syllables(&self, text: &str) -> usize {
65        let re = Regex::new(r"[aeiouyAEIOUY]+").unwrap();
66        re.find_iter(text).count()
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn test_english() {
76        let fre = FleschReadingEase::new(Language::English);
77        let text = "This is a test sentence. It is designed to check the Flesch Reading Ease score.";
78        let score = fre.calculate(text);
79        assert!(score >= 0.0 && score <= 100.0);
80    }
81
82    #[test]
83    fn test_french() {
84        let fre = FleschReadingEase::new(Language::French);
85        let text = "Ceci est une phrase de test. Elle est conçue pour vérifier le score de lisibilité de Flesch.";
86        let score = fre.calculate(text);
87        assert!(score >= 0.0 && score <= 100.0);
88    }
89
90    #[test]
91    fn test_german() {
92        let fre = FleschReadingEase::new(Language::German);
93        let text = "Dies ist ein Testsatz. Es soll die Flesch-Lesbarkeitsbewertung überprüfen.";
94        let score = fre.calculate(text);
95        assert!(score >= 0.0 && score <= 100.0);
96    }
97
98    #[test]
99    fn test_dutch() {
100        let fre = FleschReadingEase::new(Language::Dutch);
101        let text = "Dit is een testzin. Het is ontworpen om de Flesch-leesgemakscore te controleren.";
102        let score = fre.calculate(text);
103        assert!(score >= 0.0 && score <= 100.0);
104    }
105
106    #[test]
107    fn test_polish() {
108        let fre = FleschReadingEase::new(Language::Polish);
109        let text = "To jest zdanie testowe. Jest zaprojektowane, aby sprawdzić wynik łatwości czytania Flescha.";
110        let score = fre.calculate(text);
111        assert!(score >= 0.0 && score <= 100.0);
112    }
113
114    #[test]
115    fn test_bulgarian() {
116        let fre = FleschReadingEase::new(Language::Bulgarian);
117        let text = "Това е тестово изречение. То е предназначено да провери оценката за четивност на Флеш.";
118        let score = fre.calculate(text);
119        assert!(score >= 0.0 && score <= 100.0);
120    }
121
122    #[test]
123    fn test_edge_cases() {
124        let fre = FleschReadingEase::new(Language::English);
125        let text = "";
126        let score = fre.calculate(text);
127        assert_eq!(score, 0.0);
128
129        let text = "A.";
130        let score = fre.calculate(text);
131        assert!(score >= 0.0 && score <= 100.0);
132    }
133}