#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ManufactureDate {
Manufactured {
week: Option<u8>,
year: u16,
},
ModelYear(u16),
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ManufacturerId(pub [u8; 3]);
impl ManufacturerId {
pub fn from_ascii(bytes: [u8; 3]) -> Option<Self> {
if bytes.iter().all(|&b| b.is_ascii_uppercase()) {
Some(Self(bytes))
} else {
None
}
}
pub fn as_str(&self) -> &str {
debug_assert!(
self.0.iter().all(|&b| b.is_ascii_uppercase()),
"ManufacturerId invariant violated: bytes must be ASCII uppercase A-Z, got {:?}",
self.0
);
core::str::from_utf8(&self.0).expect("ManufacturerId bytes must be ASCII uppercase A-Z")
}
}
impl core::fmt::Display for ManufacturerId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MonitorString(pub [u8; 13]);
impl MonitorString {
pub fn as_str(&self) -> &str {
let bytes = &self.0;
let end = bytes.iter().position(|&b| b == 0x0A).unwrap_or(bytes.len());
let trimmed = match bytes[..end].iter().rposition(|&b| b != b' ') {
Some(i) => &bytes[..=i],
None => &[][..],
};
core::str::from_utf8(trimmed).unwrap_or("")
}
}
impl core::fmt::Display for MonitorString {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}
impl core::ops::Deref for MonitorString {
type Target = str;
fn deref(&self) -> &str {
self.as_str()
}
}