mp4_atom/
any.rs

1use crate::*;
2
3use std::fmt;
4use std::io::Read;
5
6macro_rules! any {
7    ($($kind:ident,)*) => {
8        /// Any of the supported atoms.
9        #[derive(Clone, PartialEq)]
10        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11        pub enum Any {
12            $($kind($kind),)*
13            Unknown(FourCC, Vec<u8>),
14        }
15
16        impl Any {
17            /// Get the kind of the atom.
18            pub fn kind(&self) -> FourCC {
19                match self {
20                    $(Any::$kind(_) => $kind::KIND,)*
21                    Any::Unknown(kind, _) => *kind,
22                }
23            }
24        }
25
26        impl Decode for Any {
27            fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
28                match Self::decode_maybe(buf)? {
29                    Some(any) => Ok(any),
30                    None => Err(Error::OutOfBounds),
31                }
32            }
33        }
34
35        impl DecodeMaybe for Any {
36            fn decode_maybe<B: Buf>(buf: &mut B) -> Result<Option<Self>> {
37                let header = match Header::decode_maybe(buf)? {
38                    Some(header) => header,
39                    None => return Ok(None),
40                };
41
42                let size = header.size.unwrap_or(buf.remaining());
43                if size > buf.remaining() {
44                    return Ok(None);
45                }
46
47                Ok(Some(Self::decode_atom(&header, buf)?))
48            }
49        }
50
51        impl Encode for Any {
52            fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
53                let start = buf.len();
54                0u32.encode(buf)?;
55                self.kind().encode(buf)?;
56
57                match self {
58                    $(Any::$kind(inner) => Atom::encode_body(inner, buf),)*
59                    Any::Unknown(_, data) => data.encode(buf),
60                }?;
61
62                let size: u32 = (buf.len() - start).try_into().map_err(|_| Error::TooLarge(self.kind()))?;
63                buf.set_slice(start, &size.to_be_bytes());
64
65                Ok(())
66            }
67        }
68
69        impl DecodeAtom for Any {
70            /// Decode the atom from a header and payload.
71            fn decode_atom<B: Buf>(header: &Header, buf: &mut B) -> Result<Self> {
72                let size = header.size.unwrap_or(buf.remaining());
73                if size > buf.remaining() {
74                    return Err(Error::OutOfBounds);
75                }
76
77                let mut body = &mut buf.slice(size);
78
79                let atom = match header.kind {
80                    $(_ if header.kind == $kind::KIND => {
81                        Any::$kind(match $kind::decode_body(&mut body) {
82                            Ok(atom) => atom,
83                            Err(Error::OutOfBounds) => return Err(Error::OverDecode($kind::KIND)),
84                            Err(Error::ShortRead) => return Err(Error::UnderDecode($kind::KIND)),
85                            Err(err) => return Err(err),
86                        })
87                    },)*
88                    _ => {
89                        let body = Vec::decode(body)?;
90                        Any::Unknown(header.kind, body)
91                    },
92                };
93
94                if body.has_remaining() {
95                    return Err(Error::UnderDecode(header.kind));
96                }
97
98                buf.advance(size);
99
100                Ok(atom)
101            }
102        }
103
104        impl fmt::Debug for Any {
105            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106                match self {
107                    $(Any::$kind(inner) => inner.fmt(f),)*
108                    Any::Unknown(kind, body) => write!(f, "Unknown {{ kind: {:?}, size: {:?} }}", kind, body.len()),
109                }
110            }
111        }
112
113        $(impl From<$kind> for Any {
114            fn from(inner: $kind) -> Self {
115                Any::$kind(inner)
116            }
117        })*
118    };
119}
120
121any! {
122    Ftyp,
123    Styp,
124    Moov,
125        Mvhd,
126        Udta,
127            Meta,
128                Ilst,
129                    Covr,
130                    Desc,
131                    Name,
132                    Year,
133            Skip,
134        Trak,
135            Tkhd,
136            Mdia,
137                Mdhd,
138                Hdlr,
139                Minf,
140                    Stbl,
141                        Stsd,
142                            Avc1,
143                                Avcc,
144                            Hev1,
145                                Hvcc,
146                            Mp4a,
147                                Esds,
148                            Tx3g,
149                            Vp09,
150                            Av01,
151                                Av1c,
152                        Stts,
153                        Stsc,
154                        Stsz,
155                        Stss,
156                        Stco,
157                        Co64,
158                        Ctts,
159                    Dinf,
160                        Dref,
161                    Smhd,
162                    Vmhd,
163            Edts,
164                Elst,
165        Mvex,
166            Mehd,
167            Trex,
168    Emsg,
169    Moof,
170        Mfhd,
171        Traf,
172            Tfhd,
173            Tfdt,
174            Trun,
175    Mdat,
176    Free,
177}
178
179impl ReadFrom for Any {
180    fn read_from<R: Read>(r: &mut R) -> Result<Self> {
181        <Option<Any> as ReadFrom>::read_from(r)?.ok_or(Error::UnexpectedEof)
182    }
183}
184
185impl ReadFrom for Option<Any> {
186    fn read_from<R: Read>(r: &mut R) -> Result<Self> {
187        let header = match <Option<Header> as ReadFrom>::read_from(r)? {
188            Some(header) => header,
189            None => return Ok(None),
190        };
191
192        let body = &mut header.read_body(r)?;
193        Ok(Some(Any::decode_atom(&header, body)?))
194    }
195}
196
197impl ReadAtom for Any {
198    fn read_atom<R: Read>(header: &Header, r: &mut R) -> Result<Self> {
199        let body = &mut header.read_body(r)?;
200        Any::decode_atom(header, body)
201    }
202}