mediasan_common/parse/
fourcc.rs

1use std::fmt;
2use std::io;
3
4use bytes::Buf;
5use bytes::BufMut;
6use futures_util::{pin_mut, AsyncRead, AsyncReadExt};
7
8/// A four-byte character code.
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub struct FourCC {
11    /// The character code, as an array of four bytes.
12    pub value: [u8; 4],
13}
14
15impl FourCC {
16    /// The encoded length of a [`FourCC`], in bytes.
17    pub const ENCODED_LEN: u32 = 4;
18
19    /// Construct a [`FourCC`] from a string.
20    pub const fn from_str(name: &str) -> Self {
21        let name = name.as_bytes();
22        let mut fourcc = [b' '; 4];
23        let mut name_idx = 0;
24        while name_idx < name.len() {
25            fourcc[name_idx] = name[name_idx];
26            name_idx += 1;
27        }
28        FourCC { value: fourcc }
29    }
30
31    /// Return the size of a [`FourCC`].
32    pub const fn size() -> u64 {
33        4
34    }
35
36    /// Read a [`FourCC`] from an [`AsyncRead`].
37    pub async fn read<R: AsyncRead>(input: R) -> io::Result<Self> {
38        let mut value = [0; 4];
39        pin_mut!(input);
40        input.read_exact(&mut value).await?;
41        Ok(Self { value })
42    }
43
44    /// Parse a [`FourCC`] from a [`Buf`].
45    ///
46    /// The position of `input` is advanced by 4.
47    ///
48    /// # Panics
49    ///
50    /// This function panics if `input.remaining() < 4`.
51    pub fn parse<B: Buf>(mut input: B) -> Self {
52        let mut value = [0; 4];
53        input.copy_to_slice(&mut value);
54        Self { value }
55    }
56
57    /// Writes `self` to the [`BufMut`] `out`.
58    pub fn put_buf<B: BufMut>(&self, mut out: B) {
59        out.put(&self.value[..])
60    }
61}
62
63impl fmt::Display for FourCC {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        if let Ok(string) = std::str::from_utf8(&self.value) {
66            let string = string.trim();
67            write!(f, "{string}")
68        } else {
69            write!(f, "0x{:08x}", u32::from_be_bytes(self.value))
70        }
71    }
72}