spreadsheet_to_json/
is_truthy.rs1use std::sync::Arc;
2
3use simple_string_patterns::*;
4
5pub fn is_truthy_core(txt: &str, empty_is_false: bool) -> Option<bool> {
7 let test_str = txt.trim().to_lowercase();
8 match test_str.as_str() {
9 "" => {
10 if empty_is_false {
11 Some(false)
12 } else {
13 None
14 }
15 },
16 "0" | "-1" | "false" => Some(false),
17 "1" | "2" | "true" => Some(true),
18 _ => if test_str.is_digits_only() {
19 if let Some(int_val) = test_str.to_first_number::<u8>() {
20 Some(int_val > 0)
21 } else {
22 None
23 }
24 } else {
25 None
26 }
27 }
28}
29
30pub fn is_truthy_standard(txt: &str, empty_is_false: bool) -> Option<bool> {
32 let test_str = txt.trim().to_lowercase();
33 if let Some(core_match) = is_truthy_core(txt, empty_is_false) {
34 Some(core_match)
35 } else {
36 match test_str.as_str() {
37 "no" | "not" | "none" | "n" | "f" => Some(false),
38 "ok" | "okay" |"y" | "yes" | "t" => Some(true),
39 _ => None
40 }
41 }
42}
43
44#[allow(dead_code)]
47pub fn is_truthy_custom(txt: &str, opts: &[TruthyOption], use_defaults: bool, empty_is_false: bool) -> Option<bool> {
48 let txt = txt.trim();
50 for opt in opts {
51 let letters = opt.sample();
52 if opt.starts_with {
53 if opt.case_sensitive {
54 if txt.starts_with(&letters) {
55 return Some(opt.is_true)
56 }
57 } else {
58 if txt.starts_with_ci_alphanum(&letters) {
59 return Some(opt.is_true)
60 }
61 }
62 } else {
63 if opt.case_sensitive {
64 if txt == letters {
65 return Some(opt.is_true)
66 }
67 } else {
68 if txt.to_lowercase() == letters.to_lowercase() {
69 return Some(opt.is_true);
70 }
71 }
72 }
73 }
74 if use_defaults {
75 is_truthy_core(txt, empty_is_false)
76 } else {
77 None
78 }
79}
80
81#[derive(Debug, Clone)]
85pub struct TruthyOption {
86 pub is_true: bool,
87 pub pattern: Arc<str>,
88 pub case_sensitive: bool,
89 pub starts_with: bool
90}
91
92impl TruthyOption {
93 pub fn new(is_true: bool, pattern: &str, case_sensitive: bool, starts_with: bool) -> Self {
94 Self {
95 is_true,
96 pattern: Arc::from(pattern),
97 case_sensitive,
98 starts_with
99 }
100 }
101
102 pub fn sample(&self) -> String {
103 self.pattern.to_string()
104 }
105}
106
107pub fn extract_truth_patterns(opts: &[TruthyOption], is_true: bool) -> Vec<String> {
108 opts.into_iter()
109 .filter(|&o| o.is_true == is_true)
110 .map(|o| o.pattern.to_string()).collect()
111}
112
113#[allow(dead_code)]
117pub fn split_truthy_custom_option_str(custom_str: &str, case_sensitive: bool, starts_with: bool) -> Vec<TruthyOption> {
118 let (head, tail) = custom_str.to_head_tail(":");
119 let (first, second) = tail.to_head_tail(",");
120 if first.len() > 0 {
121 if head.starts_with_ci_alphanum("tr") {
122 return to_truth_options(&first, &second, case_sensitive, starts_with)
123 }
124 }
125 vec![]
126}
127
128
129pub fn to_truth_options(true_str: &str, false_str: &str, case_sensitive: bool, starts_with: bool) -> Vec<TruthyOption> {
132 let mut matchers:Vec<TruthyOption> = vec![];
133 let true_parts = true_str.to_segments("|");
134 let false_parts = false_str.to_segments("|");
135 for match_str in true_parts {
136 matchers.push(TruthyOption::new(true, &match_str, case_sensitive, starts_with));
137 }
138 for match_str in false_parts {
139 matchers.push(TruthyOption::new(false, &match_str, case_sensitive, starts_with));
140 }
141 matchers
142}
143
144
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn test_truthy_1() {
152 let sample = "1";
153 assert_eq!(is_truthy_standard(sample, false), Some(true));
154
155 let sample = "0";
156 assert_eq!(is_truthy_standard(sample, false), Some(false));
157
158 let sample = "false";
159 assert_eq!(is_truthy_standard(sample, false), Some(false));
160 }
161
162 #[test]
163 fn test_truthy_2() {
164 let sample = "n";
165 assert_eq!(is_truthy_standard(sample, false), Some(false));
166
167 let sample = "Ok";
168 assert_eq!(is_truthy_standard(sample, false), Some(true));
169
170 let sample = "false";
171 assert_eq!(is_truthy_standard(sample, false), Some(false));
172 }
173
174 #[test]
175 fn test_truthy_custom() {
176
177 let custom_setting_str = "truthy:si|vero,no|falso";
178 let custom_flags = split_truthy_custom_option_str(custom_setting_str, false, false);
179
180 let sample = "yes";
182 assert_eq!(is_truthy_custom(sample, &custom_flags, true, false), None);
183
184 let sample = "false";
186 assert_eq!(is_truthy_custom(sample, &custom_flags, false, false), None);
187
188 let sample = "si";
189 assert_eq!(is_truthy_custom(sample, &custom_flags, true, true), Some(true));
190 }
191}