use crate::error::{Result, VeltrixError};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BoolParseMode {
Strict,
Permissive,
}
pub fn yes_no(value: bool) -> &'static str {
if value { "yes" } else { "no" }
}
pub fn on_off(value: bool) -> &'static str {
if value { "on" } else { "off" }
}
pub fn enabled_disabled(value: bool) -> &'static str {
if value { "enabled" } else { "disabled" }
}
pub fn true_false(value: bool) -> &'static str {
if value { "true" } else { "false" }
}
pub fn parse_bool(value: &str, mode: BoolParseMode) -> Result<bool> {
let normalized = value.trim().to_ascii_lowercase();
match normalized.as_str() {
"true" => Ok(true),
"false" => Ok(false),
_ if mode == BoolParseMode::Permissive => parse_truthy_falsy(&normalized),
_ => Err(VeltrixError::validation(
"bool",
format!("unsupported boolean value: {value}"),
)),
}
}
pub fn parse_truthy_falsy(value: &str) -> Result<bool> {
match value.trim().to_ascii_lowercase().as_str() {
"true" | "t" | "1" | "y" | "yes" | "on" | "enabled" | "active" | "up" | "open"
| "connected" | "pass" => Ok(true),
"false" | "f" | "0" | "n" | "no" | "off" | "disabled" | "inactive" | "down" | "closed"
| "disconnected" | "fail" => Ok(false),
_ => Err(VeltrixError::validation(
"bool",
format!("unsupported truthy/falsy value: {value}"),
)),
}
}
pub fn is_true(value: &str) -> bool {
parse_truthy_falsy(value).unwrap_or(false)
}
pub fn is_false(value: &str) -> bool {
matches!(parse_truthy_falsy(value), Ok(false))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_strict_and_permissive_bools() {
assert!(parse_bool("true", BoolParseMode::Strict).unwrap());
assert!(parse_bool("yes", BoolParseMode::Strict).is_err());
assert!(parse_bool("yes", BoolParseMode::Permissive).unwrap());
assert!(!parse_truthy_falsy("off").unwrap());
}
#[test]
fn formats_common_pairs() {
assert_eq!(yes_no(true), "yes");
assert_eq!(on_off(false), "off");
assert_eq!(enabled_disabled(true), "enabled");
assert_eq!(true_false(false), "false");
}
}