1use nutype_enum::nutype_enum;
4
5use crate::{IsoBox, IsoSized, UnknownBox};
6
7nutype_enum! {
8 pub enum Brand([u8; 4]) {
12 Mp41 = *b"mp41",
14 IsoM = *b"isom",
16 Avc1 = *b"avc1",
18 Iso2 = *b"iso2",
20 Mp71 = *b"mp71",
22 Iso3 = *b"iso3",
24 Iso4 = *b"iso4",
26 Iso5 = *b"iso5",
28 Iso6 = *b"iso6",
30 Iso7 = *b"iso7",
32 Iso8 = *b"iso8",
34 Iso9 = *b"iso9",
36 IsoA = *b"isoa",
38 IsoB = *b"isob",
40 Relo = *b"relo",
42 IsoC = *b"isoc",
44 Comp = *b"comp",
46 Unif = *b"unif",
48 }
49}
50
51impl IsoSized for Brand {
52 fn size(&self) -> usize {
53 4
54 }
55}
56
57#[derive(IsoBox, Debug, PartialEq, Eq)]
61#[iso_box(box_type = b"ftyp", crate_path = crate)]
62pub struct FileTypeBox {
63 #[iso_box(from = "[u8; 4]")]
65 pub major_brand: Brand,
66 pub minor_version: u32,
68 #[iso_box(repeated, from = "[u8; 4]")]
70 pub compatible_brands: Vec<Brand>,
71}
72
73#[derive(IsoBox, Debug, PartialEq, Eq)]
77#[iso_box(box_type = b"tyco", crate_path = crate)]
78pub struct TypeCombinationBox {
79 #[iso_box(repeated, from = "[u8; 4]")]
81 pub compatible_brands: Vec<Brand>,
82}
83
84#[derive(IsoBox, Debug, PartialEq, Eq)]
88#[iso_box(box_type = b"etyp", crate_path = crate)]
89pub struct ExtendedTypeBox<'a> {
90 #[iso_box(nested_box(collect))]
92 pub compatible_combinations: Vec<TypeCombinationBox>,
93 #[iso_box(nested_box(collect_unknown))]
95 pub unknown_boxes: Vec<UnknownBox<'a>>,
96}
97
98#[cfg(test)]
99#[cfg_attr(all(test, coverage_nightly), coverage(off))]
100mod tests {
101 use scuffle_bytes_util::zero_copy::{Deserialize, Slice};
102
103 use crate::boxes::{Brand, ExtendedTypeBox, TypeCombinationBox};
104
105 #[test]
106 fn demux_tyco() {
107 #[rustfmt::skip]
108 let data = [
109 0x00, 0x00, 0x00, 0x0C, b't', b'y', b'c', b'o', b'i', b's', b'o', b'6', 0x01,
113 ];
114
115 let mdat = TypeCombinationBox::deserialize(Slice::from(&data[..])).unwrap();
116 assert_eq!(mdat.compatible_brands.len(), 1);
117 assert_eq!(mdat.compatible_brands[0], Brand::Iso6);
118 }
119
120 #[test]
121 fn demux_etyp() {
122 #[rustfmt::skip]
123 let data = [
124 0x00, 0x00, 0x00, 44, b'e', b't', b'y', b'p', 0x00, 0x00, 0x00, 12, b't', b'y', b'c', b'o', b'i', b's', b'o', b'm', 0x00, 0x00, 0x00, 12, b't', b'y', b'c', b'o', b'i', b's', b'o', b'6', 0x00, 0x00, 0x00, 12, b'u', b'n', b'k', b'n', 0x42, 0x00, 0x42, 0x00, ];
139
140 let mdat = ExtendedTypeBox::deserialize(Slice::from(&data[..])).unwrap();
141
142 assert_eq!(mdat.compatible_combinations.len(), 2);
143
144 assert_eq!(mdat.compatible_combinations[0].compatible_brands.len(), 1);
145 assert_eq!(mdat.compatible_combinations[0].compatible_brands[0], Brand::IsoM);
146
147 assert_eq!(mdat.compatible_combinations[1].compatible_brands.len(), 1);
148 assert_eq!(mdat.compatible_combinations[1].compatible_brands[0], Brand::Iso6);
149
150 assert_eq!(mdat.unknown_boxes.len(), 1);
151 assert_eq!(mdat.unknown_boxes[0].data.len(), 4);
152 assert_eq!(mdat.unknown_boxes[0].data.as_bytes()[0], 0x42);
153 assert_eq!(mdat.unknown_boxes[0].data.as_bytes()[1], 0x00);
154 assert_eq!(mdat.unknown_boxes[0].data.as_bytes()[2], 0x42);
155 assert_eq!(mdat.unknown_boxes[0].data.as_bytes()[3], 0x00);
156 }
157}