use core::convert::TryFrom; use core::fmt; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct BerClassFromIntError(pub(crate) ()); /// BER Object class of tag #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[repr(u8)] pub enum Class { /// `Universal` class of tags (`0b00`) Universal = 0b00, /// `Application` class of tags (`0b01`) Application = 0b01, /// `Context-Specific` class of tags (`0b10`) ContextSpecific = 0b10, /// `Private` class of tags (`0b11`) Private = 0b11, } impl Class { /// `Universal` class of tags (`0b00`) pub const UNIVERSAL: u8 = 0b00; /// `Application` class of tags (`0b01`) pub const APPLICATION: u8 = 0b01; /// `Context-Specific` class of tags (`0b10`) pub const CONTEXT_SPECIFIC: u8 = 0b10; /// `Private` class of tags (`0b11`) pub const PRIVATE: u8 = 0b11; pub const fn assert_eq(&self, class: Class) -> Result<(), crate::error::Error> { if *self as u8 == class as u8 { Ok(()) } else { Err(crate::error::Error::UnexpectedClass { expected: Some(class), actual: *self, }) } } } impl fmt::Display for Class { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match self { Class::Universal => "UNIVERSAL", Class::Application => "APPLICATION", Class::ContextSpecific => "CONTEXT-SPECIFIC", Class::Private => "PRIVATE", }; write!(f, "{}", s) } } impl TryFrom for Class { type Error = BerClassFromIntError; #[inline] fn try_from(value: u8) -> Result { match value { 0b00 => Ok(Class::Universal), 0b01 => Ok(Class::Application), 0b10 => Ok(Class::ContextSpecific), 0b11 => Ok(Class::Private), _ => Err(BerClassFromIntError(())), } } } #[cfg(test)] mod tests { use super::*; #[test] fn methods_class() { let c = Class::Universal; assert!(c.assert_eq(Class::Universal).is_ok()); assert!(c.assert_eq(Class::Private).is_err()); assert_eq!(Class::Universal.to_string().as_str(), "UNIVERSAL"); assert_eq!(Class::Application.to_string().as_str(), "APPLICATION"); assert_eq!( Class::ContextSpecific.to_string().as_str(), "CONTEXT-SPECIFIC" ); assert_eq!(Class::Private.to_string().as_str(), "PRIVATE"); assert!(Class::try_from(0b00).is_ok()); assert!(Class::try_from(0b01).is_ok()); assert!(Class::try_from(0b10).is_ok()); assert!(Class::try_from(0b11).is_ok()); assert!(Class::try_from(4).is_err()); } }