flesh_reading_ease/
lib.rs1use 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}