Skip to main content

areev_core/
verification.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum Trust {
3    Unverified,
4    Verified,
5    Contested,
6    Retracted,
7}
8
9impl Trust {
10    pub fn from_field(value: Option<&str>) -> Self {
11        match value {
12            Some("verified") => Trust::Verified,
13            Some("contested") => Trust::Contested,
14            Some("retracted") | Some("rejected") => Trust::Retracted,
15            _ => Trust::Unverified,
16        }
17    }
18
19    pub fn is_actionable(self) -> bool {
20        !matches!(self, Trust::Retracted)
21    }
22
23    pub fn is_disputed(self) -> bool {
24        matches!(self, Trust::Contested | Trust::Retracted)
25    }
26
27    pub fn priority_delta(self) -> f32 {
28        match self {
29            Trust::Retracted => -0.3,
30            Trust::Contested => -0.15,
31            Trust::Unverified | Trust::Verified => 0.0,
32        }
33    }
34
35    pub fn as_str(self) -> &'static str {
36        match self {
37            Trust::Unverified => "unverified",
38            Trust::Verified => "verified",
39            Trust::Contested => "contested",
40            Trust::Retracted => "retracted",
41        }
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn every_oms_value_maps_to_its_own_state() {
51        assert_eq!(Trust::from_field(Some("unverified")), Trust::Unverified);
52        assert_eq!(Trust::from_field(Some("verified")), Trust::Verified);
53        assert_eq!(Trust::from_field(Some("contested")), Trust::Contested);
54        assert_eq!(Trust::from_field(Some("retracted")), Trust::Retracted);
55    }
56
57    #[test]
58    fn absent_and_unknown_are_unverified() {
59        assert_eq!(Trust::from_field(None), Trust::Unverified);
60        assert_eq!(Trust::from_field(Some("")), Trust::Unverified);
61        assert_eq!(Trust::from_field(Some("banana")), Trust::Unverified);
62    }
63
64    #[test]
65    fn rejected_is_an_alias_for_retracted() {
66        assert_eq!(Trust::from_field(Some("rejected")), Trust::Retracted);
67    }
68
69    #[test]
70    fn only_retraction_withholds() {
71        assert!(!Trust::Retracted.is_actionable());
72        assert!(Trust::Contested.is_actionable());
73        assert!(Trust::Verified.is_actionable());
74        assert!(Trust::Unverified.is_actionable());
75    }
76
77    #[test]
78    fn retraction_outranks_contest_as_a_penalty() {
79        assert!(Trust::Retracted.priority_delta() < Trust::Contested.priority_delta());
80        assert_eq!(Trust::Verified.priority_delta(), 0.0);
81        assert_eq!(Trust::Unverified.priority_delta(), 0.0);
82    }
83
84    #[test]
85    fn as_str_round_trips_through_from_field() {
86        for t in [Trust::Unverified, Trust::Verified, Trust::Contested, Trust::Retracted] {
87            assert_eq!(Trust::from_field(Some(t.as_str())), t);
88        }
89    }
90}