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}