1use crate::error::BticError;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
7#[repr(u8)]
8pub enum Certainty {
9 Definite = 0,
11 Approximate = 1,
13 Uncertain = 2,
15 Unknown = 3,
17}
18
19impl Certainty {
20 pub fn from_code(code: u8) -> Result<Self, BticError> {
22 match code {
23 0 => Ok(Self::Definite),
24 1 => Ok(Self::Approximate),
25 2 => Ok(Self::Uncertain),
26 3 => Ok(Self::Unknown),
27 _ => Err(BticError::ParseError(format!(
28 "certainty code {code} out of range 0..=3"
29 ))),
30 }
31 }
32
33 pub fn code(self) -> u8 {
35 self as u8
36 }
37
38 pub fn name(self) -> &'static str {
40 match self {
41 Self::Definite => "definite",
42 Self::Approximate => "approximate",
43 Self::Uncertain => "uncertain",
44 Self::Unknown => "unknown",
45 }
46 }
47
48 pub fn least_certain(self, other: Self) -> Self {
50 std::cmp::max(self, other)
51 }
52}
53
54impl std::fmt::Display for Certainty {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 f.write_str(self.name())
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn roundtrip_all_codes() {
66 for code in 0..=3u8 {
67 let c = Certainty::from_code(code).unwrap();
68 assert_eq!(c.code(), code);
69 }
70 }
71
72 #[test]
73 fn least_certain_picks_higher() {
74 assert_eq!(
75 Certainty::Definite.least_certain(Certainty::Approximate),
76 Certainty::Approximate
77 );
78 assert_eq!(
79 Certainty::Unknown.least_certain(Certainty::Definite),
80 Certainty::Unknown
81 );
82 assert_eq!(
83 Certainty::Uncertain.least_certain(Certainty::Uncertain),
84 Certainty::Uncertain
85 );
86 }
87}