use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FourCc(pub [u8; 4]);
impl FourCc {
pub const RIFF: Self = Self(*b"RIFF");
pub const WEBP: Self = Self(*b"WEBP");
pub const VP8: Self = Self(*b"VP8 ");
pub const VP8L: Self = Self(*b"VP8L");
pub const VP8X: Self = Self(*b"VP8X");
pub const ALPH: Self = Self(*b"ALPH");
pub const ICCP: Self = Self(*b"ICCP");
pub const EXIF: Self = Self(*b"EXIF");
pub const XMP: Self = Self(*b"XMP ");
pub const ANIM: Self = Self(*b"ANIM");
pub const ANMF: Self = Self(*b"ANMF");
#[must_use]
pub const fn as_bytes(&self) -> &[u8; 4] {
&self.0
}
}
impl From<[u8; 4]> for FourCc {
fn from(bytes: [u8; 4]) -> Self {
Self(bytes)
}
}
impl fmt::Display for FourCc {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for &b in &self.0 {
if b.is_ascii_graphic() || b == b' ' {
write!(f, "{}", b as char)?;
} else {
write!(f, "\\x{b:02x}")?;
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn as_bytes_and_from_roundtrip() {
let fc = FourCc::from(*b"VP8L");
assert_eq!(fc.as_bytes(), b"VP8L");
assert_eq!(fc, FourCc::VP8L);
}
#[test]
fn vp8_space_is_distinct_from_vp8l() {
assert_ne!(FourCc::VP8, FourCc::VP8L);
assert_eq!(FourCc::VP8.as_bytes(), b"VP8 ");
}
#[test]
fn display_renders_ascii_and_escapes_controls() {
assert_eq!(FourCc::VP8.to_string(), "VP8 ");
assert_eq!(FourCc::WEBP.to_string(), "WEBP");
assert_eq!(
FourCc::from([0x00, b'A', 0x7f, b'Z']).to_string(),
"\\x00A\\x7fZ"
);
}
}