use std::fmt; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum VerificationState { Unverified, Verified, Rejected, } impl VerificationState { pub fn parse(value: &str) -> Option { Some(match value { "unverified" => Self::Unverified, "verified" => Self::Verified, "rejected" => Self::Rejected, _ => return None, }) } } #[derive(Clone, Debug, Eq, PartialEq)] pub struct VerificationRecord { pub state: VerificationState, pub source_identity: String, pub diagnostic: Option, } pub fn source_changed( _old: &VerificationRecord, source_identity: impl Into, ) -> VerificationRecord { VerificationRecord { state: VerificationState::Unverified, source_identity: source_identity.into(), diagnostic: None, } } impl fmt::Display for VerificationState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { Self::Unverified => "unverified", Self::Verified => "verified", Self::Rejected => "rejected", }) } } #[cfg(test)] mod tests { use super::*; fn record() -> VerificationRecord { VerificationRecord { state: VerificationState::Unverified, source_identity: "source-a".into(), diagnostic: None, } } #[test] fn parses_only_persisted_states() { assert_eq!( VerificationState::parse("unverified"), Some(VerificationState::Unverified) ); assert_eq!( VerificationState::parse("verified"), Some(VerificationState::Verified) ); assert_eq!( VerificationState::parse("rejected"), Some(VerificationState::Rejected) ); assert_eq!(VerificationState::parse("verifying"), None); } #[test] fn source_change_resets_state_and_diagnostic() { let mut current = record(); current.state = VerificationState::Rejected; current.diagnostic = Some("old".into()); let reset = source_changed(¤t, "source-b"); assert_eq!(reset.state, VerificationState::Unverified); assert_eq!(reset.source_identity, "source-b"); assert!(reset.diagnostic.is_none()); } }