infraqueue-lib 0.1.0

Core library for INFRAQUEUE
Documentation
use anyhow::{Context, Result};

/// Parse a boolean from a variety of common string representations.
/// Accepts: 1/0, true/false, yes/no, on/off (case-insensitive).
pub fn parse_bool(s: &str) -> Option<bool> {
    match s.to_ascii_lowercase().as_str() {
        "1" | "true" | "yes" | "on" => Some(true),
        "0" | "false" | "no" | "off" => Some(false),
        _ => None,
    }
}

/// Fetch the next token value for a flag from any iterator over Strings.
/// Returns anyhow::Error when value is missing.
pub fn take_value<I: Iterator<Item = String>>(flag: &str, it: &mut I) -> Result<String> {
    it.next().context(format!("missing value for {flag}"))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_bool_truthy() {
        for v in ["1", "true", "TRUE", "TrUe", "yes", "on"] {
            assert_eq!(parse_bool(v), Some(true));
        }
    }

    #[test]
    fn test_parse_bool_falsy() {
        for v in ["0", "false", "FALSE", "No", "off"] {
            assert_eq!(parse_bool(v), Some(false));
        }
    }

    #[test]
    fn test_parse_bool_invalid() {
        for v in ["", "-1", "truthy", "y", "n"] {
            assert_eq!(parse_bool(v), None);
        }
    }

    #[test]
    fn test_take_value_ok_and_err() {
        let mut it = vec!["abc".to_string()].into_iter();
        let v = take_value("--x", &mut it).unwrap();
        assert_eq!(v, "abc");

        let mut it2 = std::iter::empty::<String>();
        let err = take_value("--flag", &mut it2).unwrap_err();
        let msg = format!("{err}");
        assert!(msg.contains("missing value for --flag"));
    }
}