#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[cfg_attr(kani, derive(kani::Arbitrary))]
pub enum TrustLevel {
#[default]
Untrusted = 0,
Partial = 1,
Trusted = 2,
FullyTrusted = 3,
}
impl TrustLevel {
#[must_use]
pub fn is_trusted(&self) -> bool {
*self >= Self::Partial
}
#[must_use]
pub fn is_fully_trusted(&self) -> bool {
*self == Self::FullyTrusted
}
}
#[cfg(kani)]
mod kani_proofs {
use super::*;
#[kani::proof]
fn trust_level_ordering_total() {
let a: TrustLevel = kani::any();
let b: TrustLevel = kani::any();
let less = a < b;
let equal = a == b;
let greater = a > b;
let count = less as u8 + equal as u8 + greater as u8;
kani::assert(count == 1, "TrustLevel ordering must be total");
}
#[kani::proof]
fn trust_level_is_trusted_iff_at_least_partial() {
let level: TrustLevel = kani::any();
let trusted = level.is_trusted();
let at_least_partial = level >= TrustLevel::Partial;
kani::assert(trusted == at_least_partial, "is_trusted() must be true iff level >= Partial");
}
#[kani::proof]
fn trust_level_untrusted_is_minimum() {
let level: TrustLevel = kani::any();
kani::assert(TrustLevel::Untrusted <= level, "Untrusted must be the minimum trust level");
}
#[kani::proof]
fn trust_level_is_fully_trusted_iff_fully_trusted() {
let level: TrustLevel = kani::any();
let method = level.is_fully_trusted();
let expected = level == TrustLevel::FullyTrusted;
kani::assert(method == expected, "is_fully_trusted() iff FullyTrusted");
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn test_trust_level_default_succeeds() {
assert_eq!(TrustLevel::default(), TrustLevel::Untrusted);
}
#[test]
fn test_trust_level_ordering_succeeds() {
assert!(TrustLevel::Untrusted < TrustLevel::Partial);
assert!(TrustLevel::Partial < TrustLevel::Trusted);
assert!(TrustLevel::Trusted < TrustLevel::FullyTrusted);
}
#[test]
fn test_trust_level_is_trusted_succeeds() {
assert!(!TrustLevel::Untrusted.is_trusted());
assert!(TrustLevel::Partial.is_trusted());
assert!(TrustLevel::Trusted.is_trusted());
assert!(TrustLevel::FullyTrusted.is_trusted());
}
#[test]
fn test_trust_level_is_fully_trusted_succeeds() {
assert!(!TrustLevel::Untrusted.is_fully_trusted());
assert!(!TrustLevel::Partial.is_fully_trusted());
assert!(!TrustLevel::Trusted.is_fully_trusted());
assert!(TrustLevel::FullyTrusted.is_fully_trusted());
}
}