mp4_atom/moov/udta/
rtng.rs1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Rtng {
6 pub entity: FourCC,
7 pub criteria: FourCC,
8 pub language: String,
9 pub rating_info: String,
10}
11
12impl AtomExt for Rtng {
13 type Ext = ();
14
15 const KIND_EXT: FourCC = FourCC::new(b"rtng");
16
17 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
18 let entity = FourCC::decode(buf)?;
19 let criteria = FourCC::decode(buf)?;
20 let language_code = u16::decode(buf)?;
21 let language = language_string(language_code);
22 let num_remaining_bytes = buf.remaining();
23 let remaining_bytes = &mut buf.slice(num_remaining_bytes);
24 let mut rating_info =
25 String::from_utf8(remaining_bytes.to_vec()).map_err(|_| Error::InvalidSize)?;
26 if rating_info.ends_with('\0') {
27 rating_info.truncate(rating_info.len() - 1);
28 }
29 buf.advance(num_remaining_bytes);
30 Ok(Rtng {
31 entity,
32 criteria,
33 language,
34 rating_info,
35 })
36 }
37
38 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
39 self.entity.encode(buf)?;
40 self.criteria.encode(buf)?;
41 let language_code = language_code(&self.language);
42 language_code.encode(buf)?;
43 self.rating_info.as_str().encode(buf)?;
44 Ok(())
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use crate::*;
51
52 const ENCODED_RTNG: &[u8] = &[
53 0x00, 0x00, 0x00, 0x1d, 0x72, 0x74, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x50, 0x41,
54 0x41, 0x00, 0x00, 0x00, 0x00, 0x15, 0xc7, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 ];
56
57 #[test]
58 fn test_rtng_decode() {
59 let buf: &mut std::io::Cursor<&&[u8]> = &mut std::io::Cursor::new(&ENCODED_RTNG);
60 let rtng = Rtng::decode(buf).expect("failed to decode rtng");
61 assert_eq!(
62 rtng,
63 Rtng {
64 entity: b"MPAA".into(),
65 criteria: b"\0\0\0\0".into(),
66 language: "eng".into(),
67 rating_info: "G\0\0\0\0\0".into(),
68 }
69 );
70 }
71
72 #[test]
73 fn test_rtng_encode() {
74 let rtng = Rtng {
75 entity: b"MPAA".into(),
76 criteria: b"\0\0\0\0".into(),
77 language: "eng".into(),
78 rating_info: "G\0\0\0\0\0".into(),
79 };
80
81 let mut buf = Vec::new();
82 rtng.encode(&mut buf).unwrap();
83 assert_eq!(buf, ENCODED_RTNG);
84 }
85}