use crate::error::BticError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(u8)]
pub enum Certainty {
Definite = 0,
Approximate = 1,
Uncertain = 2,
Unknown = 3,
}
impl Certainty {
pub fn from_code(code: u8) -> Result<Self, BticError> {
match code {
0 => Ok(Self::Definite),
1 => Ok(Self::Approximate),
2 => Ok(Self::Uncertain),
3 => Ok(Self::Unknown),
_ => Err(BticError::ParseError(format!(
"certainty code {code} out of range 0..=3"
))),
}
}
pub fn code(self) -> u8 {
self as u8
}
pub fn name(self) -> &'static str {
match self {
Self::Definite => "definite",
Self::Approximate => "approximate",
Self::Uncertain => "uncertain",
Self::Unknown => "unknown",
}
}
pub fn least_certain(self, other: Self) -> Self {
std::cmp::max(self, other)
}
}
impl std::fmt::Display for Certainty {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.name())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn roundtrip_all_codes() {
for code in 0..=3u8 {
let c = Certainty::from_code(code).unwrap();
assert_eq!(c.code(), code);
}
}
#[test]
fn least_certain_picks_higher() {
assert_eq!(
Certainty::Definite.least_certain(Certainty::Approximate),
Certainty::Approximate
);
assert_eq!(
Certainty::Unknown.least_certain(Certainty::Definite),
Certainty::Unknown
);
assert_eq!(
Certainty::Uncertain.least_certain(Certainty::Uncertain),
Certainty::Uncertain
);
}
}