1use base_traits::AsStr;
4
5
6#[rustfmt::skip]
7mod constants {
8
9 pub(super) const FALSEY_PRECISE_STRINGS : &'static [&'static str; 10] = &[
13 "0",
14 "FALSE",
15 "False",
16 "NO",
17 "No",
18 "OFF",
19 "Off",
20 "false",
21 "no",
22 "off",
23 ];
24
25 pub(super) const TRUEY_PRECISE_STRINGS : &'static [&'static str; 10] = &[
26 "1",
27 "ON",
28 "On",
29 "TRUE",
30 "True",
31 "YES",
32 "Yes",
33 "on",
34 "true",
35 "yes",
36 ];
37
38 pub(super) const FALSEY_LOWERCASE_STRINGS : &'static [&'static str; 4] = &[
39 "false",
40 "no",
41 "off",
42 "0",
43 ];
44
45 pub(super) const TRUEY_LOWERCASE_STRINGS : &'static [&'static str; 4] = &[
46 "true",
47 "yes",
48 "on",
49 "1",
50 ];
51}
52
53
54#[derive(Clone)]
56#[derive(Debug)]
57pub enum Terms<'a> {
58 Default,
60 Strings {
63 falsey_precise_strings : &'a [&'a str],
64 falsey_lowercase_strings : &'a [&'a str],
65 truey_precise_strings : &'a [&'a str],
66 truey_lowercase_strings : &'a [&'a str],
67 },
68}
69
70fn string_is_truthy_against_(
71 s : &str,
72 sorted_precise_strings : &[&str],
73 lowercase_strings : &[&str],
74) -> bool {
75 let s = s.trim();
76
77 if sorted_precise_strings.binary_search(&s).is_ok() {
78 true
79 } else {
80 let l = s.to_ascii_lowercase();
81
82 lowercase_strings.iter().any(|&f| f == l)
83 }
84}
85
86fn string_is_truthy_with_(
87 s : &str,
88 terms : Terms,
89 stock_falsey_sorted_precise_strings : &[&str],
90 stock_falsey_lowercase_strings : &[&str],
91 stock_truey_sorted_precise_strings : &[&str],
92 stock_truey_lowercase_strings : &[&str],
93) -> Option<bool> {
94 let s = s.trim();
95
96 match terms {
97 Terms::Default => {
98 if stock_falsey_sorted_precise_strings.binary_search(&s).is_ok() {
99 return Some(false);
100 }
101 if stock_truey_sorted_precise_strings.binary_search(&s).is_ok() {
102 return Some(true);
103 }
104 },
105 Terms::Strings {
106 falsey_precise_strings,
107 truey_precise_strings,
108 ..
109 } => {
110 if falsey_precise_strings.iter().any(|&f| f == s) {
111 return Some(false);
112 }
113 if truey_precise_strings.iter().any(|&f| f == s) {
114 return Some(true);
115 }
116 },
117 };
118
119 let l = s.to_ascii_lowercase();
120 let (falsey_lowercase_strings, truey_lowercase_strings) = match terms {
121 Terms::Default => (stock_falsey_lowercase_strings, stock_truey_lowercase_strings),
122 Terms::Strings {
123 falsey_lowercase_strings,
124 truey_lowercase_strings,
125 ..
126 } => (falsey_lowercase_strings, truey_lowercase_strings),
127 };
128
129 if falsey_lowercase_strings.iter().any(|&f| f == l) {
130 return Some(false);
131 }
132 if truey_lowercase_strings.iter().any(|&f| f == l) {
133 return Some(true);
134 }
135
136 None
137}
138
139pub fn stock_term_strings() -> Terms<'static> {
144 Terms::Strings {
145 falsey_precise_strings : constants::FALSEY_PRECISE_STRINGS,
146 falsey_lowercase_strings : constants::FALSEY_LOWERCASE_STRINGS,
147 truey_precise_strings : constants::TRUEY_PRECISE_STRINGS,
148 truey_lowercase_strings : constants::TRUEY_LOWERCASE_STRINGS,
149 }
150}
151
152pub fn string_is_falsey(s : &str) -> bool {
157 string_is_truthy_against_(
158 s,
159 constants::FALSEY_PRECISE_STRINGS,
160 constants::FALSEY_LOWERCASE_STRINGS,
161 )
162}
163
164pub fn string_is_truey(s : &str) -> bool {
176 string_is_truthy_against_(
177 s,
178 constants::TRUEY_PRECISE_STRINGS,
179 constants::TRUEY_LOWERCASE_STRINGS,
180 )
181}
182
183pub fn string_is_truthy(s : &str) -> Option<bool> {
193 string_is_truthy_with_(
194 s,
195 Terms::Default,
196 constants::FALSEY_PRECISE_STRINGS,
197 constants::FALSEY_LOWERCASE_STRINGS,
198 constants::TRUEY_PRECISE_STRINGS,
199 constants::TRUEY_LOWERCASE_STRINGS,
200 )
201}
202
203pub fn string_is_truthy_with(
206 s : &str,
207 terms : Terms,
208) -> Option<bool> {
209 string_is_truthy_with_(
210 s,
211 terms,
212 constants::FALSEY_PRECISE_STRINGS,
213 constants::FALSEY_LOWERCASE_STRINGS,
214 constants::TRUEY_PRECISE_STRINGS,
215 constants::TRUEY_LOWERCASE_STRINGS,
216 )
217}
218
219pub trait Truthy {
221 fn is_falsey(&self) -> bool {
223 Some(false) == self.is_truthy()
224 }
225 fn is_truey(&self) -> bool {
227 Some(true) == self.is_truthy()
228 }
229 fn is_truthy(&self) -> Option<bool>;
232}
233
234impl<T> Truthy for T
237where
238 T : AsStr,
239{
240 fn is_truthy(&self) -> Option<bool> {
241 string_is_truthy(self.as_str())
242 }
243}
244
245
246#[cfg(test)]
247mod tests {
248 #![allow(non_snake_case)]
249
250 use super::{
251 string_is_falsey,
252 string_is_truey,
253 string_is_truthy,
254 string_is_truthy_with,
255 Terms,
256 Truthy as _,
257 };
258
259
260 #[test]
261 fn TEST_string_is_falsey_1() {
262 assert_eq!(false, string_is_falsey(""));
263
264 assert_eq!(true, string_is_falsey("0"));
265 assert_eq!(true, string_is_falsey("false"));
266 assert_eq!(true, string_is_falsey(" FALSE"));
267 assert_eq!(true, string_is_falsey("False"));
268 assert_eq!(true, string_is_falsey("FaLSe"));
269 assert_eq!(true, string_is_falsey("no"));
270 assert_eq!(true, string_is_falsey("No "));
271 assert_eq!(true, string_is_falsey("NO"));
272 assert_eq!(true, string_is_falsey(" Off "));
273 assert_eq!(true, string_is_falsey("off"));
274 assert_eq!(true, string_is_falsey("OFF"));
275
276 assert_eq!(false, string_is_falsey("1"));
277 assert_eq!(false, string_is_falsey("true"));
278 assert_eq!(false, string_is_falsey("TRUE"));
279 assert_eq!(false, string_is_falsey("True"));
280 assert_eq!(false, string_is_falsey("tRuE"));
281 assert_eq!(false, string_is_falsey("yes"));
282 assert_eq!(false, string_is_falsey(" YES"));
283 assert_eq!(false, string_is_falsey("Yes "));
284 assert_eq!(false, string_is_falsey("yEs"));
285 }
286
287 #[test]
288 fn TEST_string_is_truey_1() {
289 assert_eq!(false, string_is_truey(""));
290
291 assert_eq!(false, string_is_truey("0"));
292 assert_eq!(false, string_is_truey("false"));
293 assert_eq!(false, string_is_truey(" FALSE"));
294 assert_eq!(false, string_is_truey("False"));
295 assert_eq!(false, string_is_truey("FaLSe"));
296 assert_eq!(false, string_is_truey("no"));
297 assert_eq!(false, string_is_truey("No "));
298 assert_eq!(false, string_is_truey("NO"));
299 assert_eq!(false, string_is_truey(" Off "));
300 assert_eq!(false, string_is_truey("off"));
301 assert_eq!(false, string_is_truey("OFF"));
302
303 assert_eq!(true, string_is_truey("1"));
304 assert_eq!(true, string_is_truey("true"));
305 assert_eq!(true, string_is_truey("TRUE"));
306 assert_eq!(true, string_is_truey("True"));
307 assert_eq!(true, string_is_truey("tRuE"));
308 assert_eq!(true, string_is_truey("yes"));
309 assert_eq!(true, string_is_truey(" YES"));
310 assert_eq!(true, string_is_truey("Yes "));
311 assert_eq!(true, string_is_truey("yEs"));
312 }
313
314 #[test]
315 fn TEST_string_is_truthy_1() {
316 assert_eq!(None, string_is_truthy(""));
317
318 assert_eq!(None, string_is_truthy("Nyet"));
319 assert_eq!(None, string_is_truthy("NYET"));
320 assert_eq!(None, string_is_truthy("nyET"));
321 assert_eq!(None, string_is_truthy("nope"));
322 assert_eq!(None, string_is_truthy("Nope"));
323 assert_eq!(None, string_is_truthy("NOPE"));
324
325 assert_eq!(None, string_is_truthy("Da"));
326 assert_eq!(None, string_is_truthy("DA"));
327 assert_eq!(None, string_is_truthy("dA"));
328 assert_eq!(None, string_is_truthy("yup"));
329 assert_eq!(None, string_is_truthy("Yup"));
330 assert_eq!(None, string_is_truthy("yUp"));
331
332 assert_eq!(Some(false), string_is_truthy("0"));
333 assert_eq!(Some(false), string_is_truthy("false"));
334 assert_eq!(Some(false), string_is_truthy(" FALSE"));
335 assert_eq!(Some(false), string_is_truthy("False"));
336 assert_eq!(Some(false), string_is_truthy("FaLSe"));
337 assert_eq!(Some(false), string_is_truthy("no"));
338 assert_eq!(Some(false), string_is_truthy("No "));
339 assert_eq!(Some(false), string_is_truthy("NO"));
340 assert_eq!(Some(false), string_is_truthy(" Off "));
341 assert_eq!(Some(false), string_is_truthy("off"));
342 assert_eq!(Some(false), string_is_truthy("OFF"));
343
344 assert_eq!(Some(true), string_is_truthy("1"));
345 assert_eq!(Some(true), string_is_truthy("true"));
346 assert_eq!(Some(true), string_is_truthy("TRUE"));
347 assert_eq!(Some(true), string_is_truthy("True"));
348 assert_eq!(Some(true), string_is_truthy("tRuE"));
349 assert_eq!(Some(true), string_is_truthy("yes"));
350 assert_eq!(Some(true), string_is_truthy(" YES"));
351 assert_eq!(Some(true), string_is_truthy("Yes "));
352 assert_eq!(Some(true), string_is_truthy("yEs"));
353 }
354
355 #[test]
356 fn TEST_string_is_truthy_with_1() {
357 #[rustfmt::skip]
358 const TRUEY_PRECISE_STRINGS : &[&str] = &[
359 "Da",
360 "YUP",
361 "Yup",
362 ];
363 #[rustfmt::skip]
364 const TRUEY_LOWERCASE_STRINGS : &[&str] = &[
365 "da",
366 "yup",
367 ];
368 #[rustfmt::skip]
369 const FALSEY_PRECISE_STRINGS : &[&str] = &[
370 "Nyet",
371 "Nope",
372 ];
373 #[rustfmt::skip]
374 const FALSEY_LOWERCASE_STRINGS : &[&str] = &[
375 "nyet",
376 "nope",
377 ];
378
379 let terms = Terms::Strings {
380 falsey_precise_strings : FALSEY_PRECISE_STRINGS,
381 falsey_lowercase_strings : FALSEY_LOWERCASE_STRINGS,
382 truey_precise_strings : TRUEY_PRECISE_STRINGS,
383 truey_lowercase_strings : TRUEY_LOWERCASE_STRINGS,
384 };
385
386 assert_eq!(Some(false), string_is_truthy_with("Nyet", terms.clone()));
387 assert_eq!(Some(false), string_is_truthy_with("NYET", terms.clone()));
388 assert_eq!(Some(false), string_is_truthy_with("nyET", terms.clone()));
389 assert_eq!(Some(false), string_is_truthy_with("nope", terms.clone()));
390 assert_eq!(Some(false), string_is_truthy_with("Nope", terms.clone()));
391 assert_eq!(Some(false), string_is_truthy_with("NOPE", terms.clone()));
392
393 assert_eq!(Some(true), string_is_truthy_with("Da", terms.clone()));
394 assert_eq!(Some(true), string_is_truthy_with("DA", terms.clone()));
395 assert_eq!(Some(true), string_is_truthy_with("dA", terms.clone()));
396 assert_eq!(Some(true), string_is_truthy_with("yup", terms.clone()));
397 assert_eq!(Some(true), string_is_truthy_with("Yup", terms.clone()));
398 assert_eq!(Some(true), string_is_truthy_with("yUp", terms.clone()));
399
400 assert_eq!(None, string_is_truthy_with("", terms.clone()));
401
402 assert_eq!(None, string_is_truthy_with("0", terms.clone()));
403 assert_eq!(None, string_is_truthy_with("false", terms.clone()));
404 assert_eq!(None, string_is_truthy_with(" FALSE", terms.clone()));
405 assert_eq!(None, string_is_truthy_with("False", terms.clone()));
406 assert_eq!(None, string_is_truthy_with("FaLSe", terms.clone()));
407 assert_eq!(None, string_is_truthy_with("no", terms.clone()));
408 assert_eq!(None, string_is_truthy_with("No ", terms.clone()));
409 assert_eq!(None, string_is_truthy_with("NO", terms.clone()));
410 assert_eq!(None, string_is_truthy_with(" Off ", terms.clone()));
411 assert_eq!(None, string_is_truthy_with("off", terms.clone()));
412 assert_eq!(None, string_is_truthy_with("OFF", terms.clone()));
413
414 assert_eq!(None, string_is_truthy_with("1", terms.clone()));
415 assert_eq!(None, string_is_truthy_with("true", terms.clone()));
416 assert_eq!(None, string_is_truthy_with("TRUE", terms.clone()));
417 assert_eq!(None, string_is_truthy_with("True", terms.clone()));
418 assert_eq!(None, string_is_truthy_with("tRuE", terms.clone()));
419 assert_eq!(None, string_is_truthy_with("yes", terms.clone()));
420 assert_eq!(None, string_is_truthy_with(" YES", terms.clone()));
421 assert_eq!(None, string_is_truthy_with("Yes ", terms.clone()));
422 assert_eq!(None, string_is_truthy_with("yEs", terms.clone()));
423 }
424
425 #[test]
426 fn TEST_str_Truthy_is_falsey_1() {
427 assert_eq!(false, "".is_falsey());
428
429 assert_eq!(true, "0".is_falsey());
430 assert_eq!(true, "false".is_falsey());
431 assert_eq!(true, " FALSE".is_falsey());
432 assert_eq!(true, "False".is_falsey());
433 assert_eq!(true, "FaLSe".is_falsey());
434 assert_eq!(true, "no".is_falsey());
435 assert_eq!(true, "No ".is_falsey());
436 assert_eq!(true, "NO".is_falsey());
437 assert_eq!(true, " Off ".is_falsey());
438 assert_eq!(true, "off".is_falsey());
439 assert_eq!(true, "OFF".is_falsey());
440
441 assert_eq!(false, "1".is_falsey());
442 assert_eq!(false, "true".is_falsey());
443 assert_eq!(false, "TRUE".is_falsey());
444 assert_eq!(false, "True".is_falsey());
445 assert_eq!(false, "tRuE".is_falsey());
446 assert_eq!(false, "yes".is_falsey());
447 assert_eq!(false, " YES".is_falsey());
448 assert_eq!(false, "Yes ".is_falsey());
449 assert_eq!(false, "yEs".is_falsey());
450 }
451
452 #[test]
453 fn TEST_str_Truthy_is_truey_1() {
454 assert_eq!(false, "".is_truey());
455
456 assert_eq!(false, "0".is_truey());
457 assert_eq!(false, "false".is_truey());
458 assert_eq!(false, " FALSE".is_truey());
459 assert_eq!(false, "False".is_truey());
460 assert_eq!(false, "FaLSe".is_truey());
461 assert_eq!(false, "no".is_truey());
462 assert_eq!(false, "No ".is_truey());
463 assert_eq!(false, "NO".is_truey());
464 assert_eq!(false, " Off ".is_truey());
465 assert_eq!(false, "off".is_truey());
466 assert_eq!(false, "OFF".is_truey());
467
468 assert_eq!(true, "1".is_truey());
469 assert_eq!(true, "true".is_truey());
470 assert_eq!(true, "TRUE".is_truey());
471 assert_eq!(true, "True".is_truey());
472 assert_eq!(true, "tRuE".is_truey());
473 assert_eq!(true, "yes".is_truey());
474 assert_eq!(true, " YES".is_truey());
475 assert_eq!(true, "Yes ".is_truey());
476 assert_eq!(true, "yEs".is_truey());
477 }
478}