1#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
2
3mod exceptions;
4use grapheme_picker::{drop_last, drop_lasts, take_last, take_lasts};
5
6#[must_use]
11pub fn pluralize_word(word: &str) -> String {
12 if word == "" {
29 return String::new();
30 }
31 if word == "ail" {
32 return String::from("aulx");
33 }
34 if word == "oeil" {
35 return String::from("yeux");
36 }
37 if word == "viel" {
38 return String::from("vieux");
39 }
40 if word == "topos" {
42 return String::from("topo\u{ef}");
43 }
44 if word == "d\u{fb}" {
46 return String::from("dus");
47 }
48
49 let result = String::from(word);
51 let last = take_last(word);
52
53 if exceptions::Y.contains(&word) {
55 return drop_last(word) + "ies";
56 }
57
58 if last == "s" || last == "x" || last == "z" {
60 return result;
61 }
62
63 let last_2_graphemes = take_lasts(word, 2);
65 let last2 = last_2_graphemes.as_str();
66
67 if last2 == "au" || last2 == "eu" || last2 == "ou" || last2 == "al" || last2 == "\u{153}u" {
68 return match last2 {
69 "ou" => {
71 if exceptions::OU.contains(&word) {
72 result + "x"
73 } else {
74 result + "s"
75 }
76 }
77 "eu" | "au" | "\u{153}u" => {
78 if exceptions::AU.contains(&word) || exceptions::EU.contains(&word) {
79 result + "s"
80 } else {
81 result + "x"
82 }
83 }
84 "al" => {
85 if exceptions::AL.contains(&word) {
86 result + "s"
87 } else {
88 drop_last(word) + "ux"
89 }
90 }
91 _ => result,
93 };
94 }
95
96 let last_3_graphemes = take_lasts(word, 3);
98 let last3 = last_3_graphemes.as_str();
99 if last3 == "ail" && exceptions::AIL.contains(&word) {
100 return drop_lasts(word, 2) + "ux";
101 }
102 result + "s"
104}
105
106#[cfg(test)]
107#[allow(clippy::non_ascii_literal)]
108mod tests {
109 use super::pluralize_word;
110 #[test]
111 fn pluralize_works() {
112 assert_eq!(pluralize_word(""), "");
113 assert_eq!(pluralize_word("a"), "as");
114 assert_eq!(pluralize_word("oeil"), "yeux");
115 assert_eq!(pluralize_word("tests"), "tests");
116 assert_eq!(pluralize_word("houx"), "houx");
117 assert_eq!(pluralize_word("nez"), "nez");
118 assert_eq!(pluralize_word("bleu"), "bleus");
119 assert_eq!(pluralize_word("vieu"), "vieux");
120 assert_eq!(pluralize_word("vœu"), "vœux");
121 assert_eq!(pluralize_word("bateau"), "bateaux");
122 assert_eq!(pluralize_word("landau"), "landaus");
123 assert_eq!(pluralize_word("bijou"), "bijoux");
124 assert_eq!(pluralize_word("matou"), "matous");
125 assert_eq!(pluralize_word("animal"), "animaux");
126 assert_eq!(pluralize_word("festival"), "festivals");
127 assert_eq!(pluralize_word("corail"), "coraux");
128 assert_eq!(pluralize_word("émail"), "émaux");
129 assert_eq!(pluralize_word("chandail"), "chandails");
130 assert_eq!(pluralize_word("voiture"), "voitures");
131 assert_eq!(pluralize_word("vélo"), "vélos");
132 }
133}