use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OwlProfile {
Rl,
El,
Ql,
RlEl,
Dl,
}
impl OwlProfile {
pub fn short_name(self) -> &'static str {
match self {
Self::Rl => "RL",
Self::El => "EL",
Self::Ql => "QL",
Self::RlEl => "RLEL",
Self::Dl => "DL",
}
}
pub fn parse(name: &str) -> Option<Self> {
match name.trim().to_ascii_uppercase().as_str() {
"RL" => Some(Self::Rl),
"EL" => Some(Self::El),
"QL" => Some(Self::Ql),
"RLEL" | "RL+EL" | "EL+RL" | "ELRL" => Some(Self::RlEl),
"DL" => Some(Self::Dl),
_ => None,
}
}
pub fn all() -> &'static [Self] {
&[Self::Rl, Self::El, Self::Ql, Self::RlEl, Self::Dl]
}
pub fn is_tractable(self) -> bool {
matches!(self, Self::Rl | Self::El | Self::Ql | Self::RlEl)
}
}
impl fmt::Display for OwlProfile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.short_name())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_trip_short_names() {
for profile in OwlProfile::all() {
let parsed = OwlProfile::parse(profile.short_name())
.expect("parsing canonical short name should succeed");
assert_eq!(parsed, *profile);
}
}
#[test]
fn parse_aliases_and_case_insensitivity() {
assert_eq!(OwlProfile::parse("rl"), Some(OwlProfile::Rl));
assert_eq!(OwlProfile::parse(" RL+EL "), Some(OwlProfile::RlEl));
assert_eq!(OwlProfile::parse("ELrl"), Some(OwlProfile::RlEl));
assert_eq!(OwlProfile::parse("rlel"), Some(OwlProfile::RlEl));
assert_eq!(OwlProfile::parse("dl"), Some(OwlProfile::Dl));
assert_eq!(OwlProfile::parse("foo"), None);
}
#[test]
fn tractability_classification() {
assert!(OwlProfile::Rl.is_tractable());
assert!(OwlProfile::El.is_tractable());
assert!(OwlProfile::Ql.is_tractable());
assert!(OwlProfile::RlEl.is_tractable());
assert!(!OwlProfile::Dl.is_tractable());
}
#[test]
fn display_matches_short_name() {
assert_eq!(format!("{}", OwlProfile::Rl), "RL");
assert_eq!(format!("{}", OwlProfile::RlEl), "RLEL");
}
}