1use anyhow::{Context, Result};
2
3pub fn parse_bool(s: &str) -> Option<bool> {
6 match s.to_ascii_lowercase().as_str() {
7 "1" | "true" | "yes" | "on" => Some(true),
8 "0" | "false" | "no" | "off" => Some(false),
9 _ => None,
10 }
11}
12
13pub fn take_value<I: Iterator<Item = String>>(flag: &str, it: &mut I) -> Result<String> {
16 it.next().context(format!("missing value for {flag}"))
17}
18
19#[cfg(test)]
20mod tests {
21 use super::*;
22
23 #[test]
24 fn test_parse_bool_truthy() {
25 for v in ["1", "true", "TRUE", "TrUe", "yes", "on"] {
26 assert_eq!(parse_bool(v), Some(true));
27 }
28 }
29
30 #[test]
31 fn test_parse_bool_falsy() {
32 for v in ["0", "false", "FALSE", "No", "off"] {
33 assert_eq!(parse_bool(v), Some(false));
34 }
35 }
36
37 #[test]
38 fn test_parse_bool_invalid() {
39 for v in ["", "-1", "truthy", "y", "n"] {
40 assert_eq!(parse_bool(v), None);
41 }
42 }
43
44 #[test]
45 fn test_take_value_ok_and_err() {
46 let mut it = vec!["abc".to_string()].into_iter();
47 let v = take_value("--x", &mut it).unwrap();
48 assert_eq!(v, "abc");
49
50 let mut it2 = std::iter::empty::<String>();
51 let err = take_value("--flag", &mut it2).unwrap_err();
52 let msg = format!("{err}");
53 assert!(msg.contains("missing value for --flag"));
54 }
55}