#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PasswordLoginPolicy {
Enabled,
Disabled,
}
impl PasswordLoginPolicy {
pub fn parse(raw: &str) -> Option<Self> {
match raw.trim().to_ascii_lowercase().as_str() {
"enabled" | "on" | "1" | "true" => Some(Self::Enabled),
"disabled" | "off" | "0" | "false" => Some(Self::Disabled),
_ => None,
}
}
#[must_use]
pub fn is_enabled(self) -> bool {
matches!(self, Self::Enabled)
}
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
Self::Enabled => "enabled",
Self::Disabled => "disabled",
}
}
}
#[cfg(test)]
mod tests {
use super::PasswordLoginPolicy;
#[test]
fn test_parse_accepts_enabled_spellings() {
for raw in ["enabled", "ENABLED", "Enabled", "eNaBlEd"] {
assert_eq!(
PasswordLoginPolicy::parse(raw),
Some(PasswordLoginPolicy::Enabled),
"expected {raw:?} to parse as Enabled"
);
}
}
#[test]
fn test_parse_accepts_disabled_spellings() {
for raw in ["disabled", "DISABLED", "Disabled", "dIsAbLeD"] {
assert_eq!(
PasswordLoginPolicy::parse(raw),
Some(PasswordLoginPolicy::Disabled),
"expected {raw:?} to parse as Disabled"
);
}
}
#[test]
fn test_parse_accepts_on_off_numerics_and_booleans() {
for raw in ["on", "ON", "1", "true", "TRUE", "True"] {
assert_eq!(
PasswordLoginPolicy::parse(raw),
Some(PasswordLoginPolicy::Enabled),
"expected {raw:?} to parse as Enabled"
);
}
for raw in ["off", "OFF", "0", "false", "FALSE", "False"] {
assert_eq!(
PasswordLoginPolicy::parse(raw),
Some(PasswordLoginPolicy::Disabled),
"expected {raw:?} to parse as Disabled"
);
}
}
#[test]
fn test_parse_trims_surrounding_whitespace() {
assert_eq!(
PasswordLoginPolicy::parse(" enabled\t"),
Some(PasswordLoginPolicy::Enabled)
);
assert_eq!(
PasswordLoginPolicy::parse("\toff\n"),
Some(PasswordLoginPolicy::Disabled)
);
}
#[test]
fn test_parse_rejects_unrecognized_values() {
for raw in [
"",
" ",
"yes",
"no",
"maybe",
"2",
"10",
"-1",
"enabled=true",
"enabled disabled",
"enalbed",
"disabeld",
"是",
"enabled",
] {
assert_eq!(
PasswordLoginPolicy::parse(raw),
None,
"expected {raw:?} to be rejected"
);
}
}
#[test]
fn test_parse_rejects_inner_separators_and_compound_values() {
for raw in ["en abled", "on//1", "true,false", "enabled=1"] {
assert_eq!(
PasswordLoginPolicy::parse(raw),
None,
"expected {raw:?} to be rejected"
);
}
}
#[test]
fn test_as_str_spellings() {
assert_eq!(PasswordLoginPolicy::Enabled.as_str(), "enabled");
assert_eq!(PasswordLoginPolicy::Disabled.as_str(), "disabled");
}
#[test]
fn test_as_str_round_trips_through_parse() {
for policy in [PasswordLoginPolicy::Enabled, PasswordLoginPolicy::Disabled] {
assert_eq!(PasswordLoginPolicy::parse(policy.as_str()), Some(policy));
}
}
#[test]
fn test_is_enabled() {
assert!(PasswordLoginPolicy::Enabled.is_enabled());
assert!(!PasswordLoginPolicy::Disabled.is_enabled());
}
#[test]
fn test_policy_is_copy_and_comparable() {
let policy = PasswordLoginPolicy::Disabled;
let copy = policy;
assert_eq!(policy, copy);
assert_ne!(policy, PasswordLoginPolicy::Enabled);
let _debug = format!("{policy:?}");
}
}