riffu/
fourcc.rs

1use crate::{error::RiffResult, RiffError};
2use std::convert::{TryFrom, TryInto};
3
4#[derive(Debug, Clone)]
5pub struct FourCC {
6    data: [u8; 4],
7}
8
9/// Represents the ASCII identifier of a chunk.
10///
11/// # Example
12///
13/// ```rust
14/// use riffu::FourCC;
15/// let good = FourCC::new(b"1234");
16/// // let bad = FourCC::new(b"12345"); // won't compile
17/// ```
18///
19/// # NOTE
20///
21/// 1. AFAIK, the only valid identifier is in ASCII.
22///    I am not entirely sure what all the possible value ASCII can take.
23///    So we need to enforce correctness on that front too.
24/// 2. Are there other conversions that we are missing out on?
25impl FourCC {
26    pub fn new(data: &[u8]) -> RiffResult<FourCC> {
27        let data = data.try_into()?;
28        Ok(FourCC { data })
29    }
30
31    /// View `&self` struct as a `&[u8]`.
32    pub fn as_bytes(&self) -> &[u8; 4] {
33        &self.data
34    }
35
36    /// Consume `self` and returns a `[u8; 4]`.
37    pub fn into_bytes(self) -> [u8; 4] {
38        self.data
39    }
40}
41
42/// A `&[u8]` can be converted to a `FourCC`.
43impl TryFrom<&[u8]> for FourCC {
44    type Error = RiffError;
45
46    /// Performs the conversion from a slice of bytes to `FourCC`.
47    /// ```
48    /// use riffu::FourCC;
49    /// use std::convert::TryInto;
50    /// let buffer: &[u8] = &[80u8, 80u8, 80u8,80u8];
51    /// let test: FourCC = buffer.try_into().unwrap();
52    /// ```
53    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
54        Ok(FourCC {
55            data: value.try_into()?,
56        })
57    }
58}
59
60/// A `&str` can be converted to a `FourCC`.
61impl TryFrom<&str> for FourCC {
62    type Error = RiffError;
63
64    /// Performs the conversion.
65    /// ```
66    /// use riffu::FourCC;
67    /// use std::convert::TryInto;
68    /// let test : FourCC = "test".try_into().unwrap();
69    /// ```
70    fn try_from(value: &str) -> Result<Self, Self::Error> {
71        value.as_bytes().try_into()
72    }
73}