1mod core_is_an;
6mod options;
7mod rules;
8mod utils;
9
10use utils::string_helper;
11
12pub use core_is_an::Is;
13pub use options::Options;
14
15pub fn get_a_or_an(word: &str) -> &str {
41 get_a_or_an_options(word, &Options::default())
42}
43
44pub fn get_a_or_an_options(word: &str, options: &Options) -> &'static str {
71 if word.trim().len() == 0 {
72 return "";
73 }
74
75 let is_an = is_an_options(word, options);
76
77 core_is_an::a_or_an_capitalized_to_match(is_an, string_helper::get_first_word(word))
78}
79
80pub fn is_an(word: &str) -> Is {
104 is_an_options(word, &Options::default())
105}
106
107pub fn is_an_options(word: &str, options: &Options) -> Is {
131 if word.trim().len() == 0 {
132 return Is::None;
133 }
134
135 if core_is_an::is_an_options_bool(word, options) {
136 return Is::An;
137 }
138
139 Is::A
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn common_words() {
148 assert_eq!("an", get_a_or_an("antelope"));
149 assert_eq!("an", get_a_or_an("apple"));
150 assert_eq!("a", get_a_or_an("pear"));
151
152 assert_eq!(Is::An, is_an("antelope"));
153 assert_eq!(Is::An, is_an("apple"));
154 assert_eq!(Is::A, is_an("pear"));
155 }
156
157 #[test]
158 fn zero_length() {
159 assert_eq!("", get_a_or_an(""));
160 assert_eq!(Is::None, is_an(""));
161 }
162
163 #[test]
164 fn all_whitespace() {
165 assert_eq!("", get_a_or_an(" "));
166 assert_eq!(Is::None, is_an(" "));
167 }
168
169 macro_rules! tests {
170 ($($name:ident: $value:expr,)*) => {
171 $(
172 #[test]
173 fn $name() {
174 let (input, expected) = $value;
175 assert_eq!(expected, get_a_or_an(input));
176 assert_eq!(expected.to_lowercase() == "an", is_an(input) == Is::An);
177 }
178 )*
179 }
180 }
181
182 macro_rules! tests_options_with_colloquial {
183 ($($name:ident: $value:expr,)*) => {
184 $(
185 #[test]
186 fn $name() {
187 let options = &(Options::with_colloquial());
188
189 let (input, expected) = $value;
190 assert_eq!(expected, get_a_or_an_options(input, options));
191 assert_eq!(expected.to_lowercase() == "an", is_an_options(input, options) == Is::An);
192 }
193 )*
194 }
195 }
196
197 tests! {
198 test_ac0: ("CEO", "a"),
200 test_ac1: ("EU", "an"),
201 test_ac2a: ("FFA", "an"),
202 test_ac2b: ("FIFA", "an"),
203 test_ac2c: ("IOU", "an"),
204 test_ac3: ("MIA", "an"),
205 test_ac4: ("MNM", "an"),
206 test_ac5: ("UFO", "a"),
207 test_ac6: ("UN", "a"),
208 test_ac7: ("US", "a"),
209 test_ac8: ("USA", "a"),
210 test_a1: ("alien", "an"),
212 test_a2a: ("american", "an"),
213 test_a2b: ("antelope", "an"),
214 test_a2c: ("apple", "an"),
215 test_a2d: ("banana", "a"),
216 test_e1: ("economic", "an"),
217 test_e2: ("economy", "an"),
218 test_eu1: ("euro", "a"),
220 test_eu2: ("european", "a"),
221 test_eu3: ("European", "A"),
222 test_eu4: ("eucalyptus", "a"),
223 test_eu5: ("eulogy", "a"),
224 test_ur1: ("uranium", "a"),
226 test_ur2: ("urinal", "a"),
227 test_ur3: ("urologist", "a"),
228 test_uni1: ("unicorn", "a"),
230 test_uni2: ("uniform", "a"),
231 test_uni3: ("unit", "a"),
232 test_uni4: ("universal", "a"),
233 test_uni5: ("university", "a"),
234 test_uni_adj1: ("unidentified", "an"),
236 test_uni_adj2: ("unimportant", "an"),
237 test_uni_adj3: ("unintended", "an"),
238 test_uni_adj4: ("unintelligent", "an"),
239 test_h1: ("hair", "a"),
241 test_h2: ("heir", "an"),
242 test_h3: ("herb", "an"), test_h4: ("hotel", "a"),
244 test_o0: ("ordinary", "an"),
245 test_o1: ("ouija", "a"),
246 test_r1: ("red", "a"),
247 test_r2: ("red rum", "a"),
248 test_r3: ("rum", "a"),
249 test_u0: ("ukelele", "a"),
250 test_u1: ("umbrella", "an"),
251 test_u2: ("user", "a"),
252 test_u2a: ("usurper", "a"),
253 test_u2b: ("usurped", "a"),
254 test_u3: ("Utah", "A"),
255 test_u4: ("utahn", "a"),
256 test_n0: ("0", "a"),
258 test_n1: ("1", "a"),
259 test_n2: ("2", "a"),
260 test_n3: ("3", "a"),
261 test_n4: ("4", "a"),
262 test_n5: ("5", "a"),
263 test_n6: ("6", "a"),
264 test_n7: ("7", "a"),
265 test_n8: ("8", "an"),
266 test_n9: ("9", "a"),
267 test_n10: ("10", "a"),
268 test_n11: ("11", "an"),
269 test_n12: ("12", "a"),
270 test_n13: ("13", "a"),
271 test_n14: ("14", "a"),
272 test_n15: ("15", "a"),
273 test_n16: ("16", "a"),
274 test_n17: ("17", "a"),
275 test_n18: ("18", "an"),
276 test_n19: ("19", "a"),
277 test_n20: ("20", "a"),
278 test_n1_000: ("1,000", "a"),
280 test_n2_000: ("2,000", "a"),
281 test_n3_000: ("3,000", "a"),
282 test_n4_000: ("4,000", "a"),
283 test_n5_000: ("5,000", "a"),
284 test_n6_000: ("6,000", "a"),
285 test_n7_000: ("7,000", "a"),
286 test_n8_000: ("8,000", "an"),
287 test_n9_000: ("9,000", "a"),
288 test_n10_000: ("10,000", "a"),
289 test_n11_000: ("11,000", "an"),
290 test_n12_000: ("12,000", "a"),
291 test_n13_000: ("13,000", "a"),
292 test_n14_000: ("14,000", "a"),
293 test_n15_000: ("15,000", "a"),
294 test_n16_000: ("16,000", "a"),
295 test_n17_000: ("17,000", "a"),
296 test_n18_000: ("18,000", "an"),
297 test_n19_000: ("19,000", "a"),
298 test_n20_000: ("20,000", "a"),
299 test_n0_5: ("0.5", "a"),
301 test_n1_5: ("1.5", "a"),
302 test_n2_5: ("2.5", "a"),
303 test_n3_5: ("3.5", "a"),
304 test_n4_5: ("4.5", "a"),
305 test_n5_5: ("5.5", "a"),
306 test_n6_5: ("6.5", "a"),
307 test_n7_5: ("7.5", "a"),
308 test_n8_5: ("8.5", "an"),
309 test_n9_5: ("9.5", "a"),
310 test_n10_5: ("10.5", "a"),
311 test_n11_5: ("11.5", "an"),
312 test_n12_5: ("12.5", "a"),
313 test_n13_5: ("13.5", "a"),
314 test_n14_5: ("14.5", "a"),
315 test_n15_5: ("15.5", "a"),
316 test_n16_5: ("16.5", "a"),
317 test_n17_5: ("17.5", "a"),
318 test_n18_5: ("18.5", "an"),
319 test_n19_5: ("19.5", "a"),
320 test_n20_5: ("20.5", "a"),
321 test_ny1000: ("1000", "a"),
323 test_ny1800: ("1800", "a"),
324 test_ny1892: ("1892", "a"),
325 test_n11_01: ("11", "an"),
327 test_n11_02: ("110", "a"),
328 test_n11_03: ("1100", "a"), test_n11_04: ("11000", "an"),
330 test_n11_05: ("110000", "a"),
331 test_n11_06: ("1100000", "a"),
332 test_n11_07: ("11000000", "an"),
333 test_n11_08: ("110000000", "a"),
334 test_n11_09: ("1100000000", "a"),
335 test_n11_10: ("11000000000", "an"),
336 test_n11_11: ("110000000000", "a"),
337 test_n11_12: ("1100000000000", "a"),
338 test_n11_13: ("11000000000000", "an"),
339 test_n11_14: ("110000000000000", "a"),
340 test_n11_15: ("1100000000000000", "a"),
341 test_n11_16: ("11000000000000000", "an"),
342 test_ns18_01: ("18", "an"),
344 test_ns18_02: ("180", "a"),
345 test_ns18_03: ("18000", "an"),
346 test_ns18_04: ("180000", "a"),
347 test_ns18_05: ("1800000", "a"),
348 test_ns18_06: ("18000000", "an"),
349 test_ns18_07: ("180000000", "a"),
350 test_ns18_08: ("1800000000", "a"),
351 test_ns18_09: ("18000000000", "an"),
352 test_ns18_10: ("180000000000", "a"),
353 test_ns18_11: ("1800000000000", "a"),
354 test_ns18_12: ("18000000000000", "an"),
355 test_ns18_13: ("180000000000000", "a"),
356 test_ns18_14: ("1800000000000000", "a"),
357 test_ns18_15: ("18000000000000000", "an"),
358 test_n8_01: ("8", "an"),
360 test_n8_02: ("80", "an"),
361 test_n8_03: ("800", "an"),
362 test_n8_04: ("8000", "an"),
363 test_n8_05: ("80000", "an"),
364 test_n8_06: ("800000", "an"),
365 test_n8_07: ("8000000", "an"),
366 test_n8_08: ("80000000", "an"),
367 test_n8_09: ("800000000", "an"),
368 test_mc1: ("Alien", "An"), test_mc2: ("anteLoPe", "an"), test_mc3: ("haiR", "a"), test_mc4: ("HEIR", "an"), test_mc5: ("Heir", "An"), test_mc6: ("Ugly", "An"), test_other1: ("ouija board", "a"),
379 test_other2: ("apple-board", "an"),
381 test_other3: ("honor-bound", "an"),
382 test_other4: ("horror-bound", "a"),
383 test_other_s1: ("heavenly", "a"),
385 test_other_s2: ("honored", "an"),
386 test_other_s3: ("hourly", "an"),
387 test_other_s4: ("heirly", "an"),
388 test_other6: ("heiresses", "an"),
390 test_other6b: ("heirs", "an"),
391 test_other7: ("honors", "an"),
392 test_other8: ("heir's", "an"),
394 test_other9: ("horror's", "a"),
395 test_other_adv1: ("ubiquitously", "a"),
397 test_other_adv2: ("ukelele", "a"),
398 test_other_adv3: ("unanimously", "a"),
399 test_other_adv4: ("unicamerally", "a"),
400 test_other_adv5: ("uniquely", "a"),
401 test_other_adv6: ("universally", "a"),
402 test_other_adv7: ("urologically", "a"),
403 test_other_adv8: ("usefully", "a"),
404 test_other_adv9: ("uselessly", "a"),
405 test_other_adv10: ("usuriously", "a"),
406 }
407
408 tests_options_with_colloquial! {
409 test_colloquial_ac1: ("EU", "an"),
410 test_colloquial_ac2: ("FIFA", "an"),
411 test_colloquial_ac3: ("MIA", "an"),
412 test_colloquial_ac4: ("MNM", "an"),
413 test_colloquial_ac4b: ("NATO", "an"),
414 test_colloquial_ac5: ("UFO", "a"),
415 test_colloquial_ac6: ("UN", "a"),
416 test_colloquial_a1: ("alien", "an"),
417 test_colloquial_a2: ("antelope", "an"),
418 test_colloquial_h1: ("hair", "a"),
419 test_colloquial_h2: ("heir", "an"),
420 test_colloquial_h3: ("herb", "an"), test_colloquial_h4: ("hotel", "a"),
422 test_colloquial_u1: ("umbrella", "an"),
423 test_colloquial_u2: ("user", "a"),
424 test_colloquial_n0: ("0", "a"),
426 test_colloquial_n1: ("1", "a"),
427 test_colloquial_n2: ("2", "a"),
428 test_colloquial_n3: ("3", "a"),
429 test_colloquial_n4: ("4", "a"),
430 test_colloquial_n5: ("5", "a"),
431 test_colloquial_n6: ("6", "a"),
432 test_colloquial_n7: ("7", "a"),
433 test_colloquial_n8: ("8", "an"),
434 test_colloquial_n9: ("9", "a"),
435 test_colloquial_n10: ("10", "a"),
436 test_colloquial_ny1000: ("1000", "a"), test_colloquial_ny1100: ("1100", "an"), test_colloquial_ny1800: ("1800", "an"),
440 test_colloquial_ny1892: ("1892", "an"),
441 test_single_irregular_u: ("u", "a"),
443 test_single_irregular_f: ("f", "an"),
444 test_single_irregular_h: ("h", "an"),
445 test_single_irregular_l: ("l", "an"),
446 test_single_irregular_m: ("m", "an"),
447 test_single_irregular_n: ("n","an"),
448 test_single_irregular_r: ("r", "an"),
449 test_single_irregular_s: ("s", "an"),
450 test_single_irregular_x: ("x", "an"),
451 test_single_regular_a: ("a", "an"),
453 test_single_regular_b: ("b", "a"),
454 }
455}