1use std::fmt;
2use std::str::FromStr;
3
4#[derive(Copy, Clone, Eq, PartialEq, Hash)]
5pub struct FourCC(pub [u8; 4]);
6
7impl FourCC {
8 pub fn as_str_lossy(&self) -> String {
9 self.0
10 .iter()
11 .map(|&c| {
12 if (32..=126).contains(&c) {
13 c as char
14 } else {
15 '.'
16 }
17 })
18 .collect()
19 }
20}
21impl fmt::Debug for FourCC {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 write!(f, "{}", self.as_str_lossy())
24 }
25}
26impl fmt::Display for FourCC {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 write!(f, "{}", self.as_str_lossy())
29 }
30}
31
32impl From<[u8; 4]> for FourCC {
33 fn from(b: [u8; 4]) -> Self {
34 FourCC(b)
35 }
36}
37
38impl FromStr for FourCC {
39 type Err = ();
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 let b = s.as_bytes();
43 if b.len() == 4 {
44 Ok(FourCC([b[0], b[1], b[2], b[3]]))
45 } else {
46 Err(())
47 }
48 }
49}
50
51#[derive(Debug, Clone)]
52pub struct BoxHeader {
53 pub size: u64, pub typ: FourCC, pub uuid: Option<[u8; 16]>,
56 pub header_size: u64, pub start: u64, }
59
60#[derive(Debug)]
61pub enum NodeKind {
62 Container(Vec<BoxRef>),
63 FullBox {
64 version: u8,
65 flags: u32,
66 data_offset: u64,
67 data_len: u64,
68 },
69 Leaf {
70 data_offset: u64,
71 data_len: u64,
72 },
73 Unknown {
74 data_offset: u64,
75 data_len: u64,
76 },
77}
78
79#[derive(Debug)]
80pub struct BoxRef {
81 pub hdr: BoxHeader,
82 pub kind: NodeKind,
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Hash)]
86pub enum BoxKey {
87 FourCC(FourCC),
88 Uuid([u8; 16]),
89}