1use crate::*;
2
3use std::fmt;
4use std::io::Read;
5
6macro_rules! any {
7 (basic: [$($kind:ident,)* $(,)?], boxed: [$($boxed:ident,)* $(,)?]) => {
8 #[derive(Clone, PartialEq)]
10 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11 #[non_exhaustive]
12 pub enum Any {
13 $($kind($kind),)*
14 $($boxed(Box<$boxed>),)*
15 Unknown(FourCC, Vec<u8>),
16 }
17
18 impl Any {
19 pub fn kind(&self) -> FourCC {
21 match self {
22 $(Any::$kind(_) => $kind::KIND,)*
23 $(Any::$boxed(_) => $boxed::KIND,)*
24 Any::Unknown(kind, _) => *kind,
25 }
26 }
27 }
28
29 impl Decode for Any {
30 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
31 match Self::decode_maybe(buf)? {
32 Some(any) => Ok(any),
33 None => Err(Error::OutOfBounds),
34 }
35 }
36 }
37
38 impl DecodeMaybe for Any {
39 fn decode_maybe<B: Buf>(buf: &mut B) -> Result<Option<Self>> {
40 let header = match Header::decode_maybe(buf)? {
41 Some(header) => header,
42 None => return Ok(None),
43 };
44
45 let size = header.size.unwrap_or(buf.remaining());
46 if size > buf.remaining() {
47 return Ok(None);
48 }
49
50 Ok(Some(Self::decode_atom(&header, buf)?))
51 }
52 }
53
54 impl Encode for Any {
55 fn encode<B: BufMut>(&self, buf: &mut B) -> Result<()> {
56 let start = buf.len();
57 0u32.encode(buf)?;
58 self.kind().encode(buf)?;
59
60 match self {
61 $(Any::$kind(inner) => Atom::encode_body(inner, buf),)*
62 $(Any::$boxed(boxed) => Atom::encode_body(boxed.as_ref(), buf),)*
63 Any::Unknown(_, data) => data.encode(buf),
64 }?;
65
66 let size: u32 = (buf.len() - start).try_into().map_err(|_| Error::TooLarge(self.kind()))?;
67 buf.set_slice(start, &size.to_be_bytes());
68
69 Ok(())
70 }
71 }
72
73 impl DecodeAtom for Any {
74 fn decode_atom<B: Buf>(header: &Header, buf: &mut B) -> Result<Self> {
76 let size = header.size.unwrap_or(buf.remaining());
77 if size > buf.remaining() {
78 return Err(Error::OutOfBounds);
79 }
80
81 let mut body = &mut buf.slice(size);
82
83 let atom = match header.kind {
84 $(_ if header.kind == $kind::KIND => {
85 Any::$kind(match $kind::decode_body(&mut body) {
86 Ok(atom) => atom,
87 Err(Error::OutOfBounds) => return Err(Error::OverDecode($kind::KIND)),
88 Err(Error::ShortRead) => return Err(Error::UnderDecode($kind::KIND)),
89 Err(err) => return Err(err),
90 })
91 },)*
92 $(_ if header.kind == $boxed::KIND => {
93 Any::$boxed(match $boxed::decode_body(&mut body) {
94 Ok(atom) => Box::new(atom),
95 Err(Error::OutOfBounds) => return Err(Error::OverDecode($boxed::KIND)),
96 Err(Error::ShortRead) => return Err(Error::UnderDecode($boxed::KIND)),
97 Err(err) => return Err(err),
98 })
99 },)*
100 _ => {
101 let body = Vec::decode(body)?;
102 Any::Unknown(header.kind, body)
103 },
104 };
105
106 if body.has_remaining() {
107 return Err(Error::UnderDecode(header.kind));
108 }
109
110 buf.advance(size);
111
112 Ok(atom)
113 }
114 }
115
116 impl fmt::Debug for Any {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 match self {
119 $(Any::$kind(inner) => inner.fmt(f),)*
120 $(Any::$boxed(boxed) => boxed.fmt(f),)*
121 Any::Unknown(kind, body) => write!(f, "Unknown {{ kind: {:?}, size: {:?}, bytes: {:?} }}", kind, body.len(), body),
122 }
123 }
124 }
125
126 $(impl From<$kind> for Any {
127 fn from(inner: $kind) -> Self {
128 Any::$kind(inner)
129 }
130 })*
131
132 $(impl From<$boxed> for Any {
133 fn from(inner: $boxed) -> Self {
134 Any::$boxed(Box::new(inner))
135 }
136 })*
137
138 $(impl TryFrom<Any> for $kind {
139 type Error = Any;
140
141 fn try_from(any: Any) -> std::result::Result<Self, Any> {
142 match any {
143 Any::$kind(inner) => Ok(inner),
144 _ => Err(any),
145 }
146 }
147 })*
148
149 $(impl TryFrom<Any> for $boxed {
150 type Error = Any;
151
152 fn try_from(any: Any) -> std::result::Result<Self, Any> {
153 match any {
154 Any::$boxed(boxed) => Ok(*boxed),
155 _ => Err(any),
156 }
157 }
158 })*
159
160 $(impl From<Box<$boxed>> for $boxed {
162 fn from(boxed: Box<$boxed>) -> Self {
163 *boxed
164 }
165 })*
166
167 pub trait AnyAtom: Atom {
170 fn from_any(any: Any) -> Option<Self>;
171 fn from_any_ref(any: &Any) -> Option<&Self>;
172 fn from_any_mut(any: &mut Any) -> Option<&mut Self>;
173
174 fn into_any(self) -> Any;
175 }
176
177 $(impl AnyAtom for $kind {
178 fn from_any(any: Any) -> Option<Self> {
179 match any {
180 Any::$kind(inner) => Some(inner),
181 _ => None,
182 }
183 }
184
185 fn from_any_ref(any: &Any) -> Option<&Self> {
186 match any {
187 Any::$kind(inner) => Some(inner),
188 _ => None,
189 }
190 }
191
192 fn from_any_mut(any: &mut Any) -> Option<&mut Self> {
193 match any {
194 Any::$kind(inner) => Some(inner),
195 _ => None,
196 }
197 }
198
199 fn into_any(self) -> Any {
200 Any::$kind(self)
201 }
202 })*
203
204 $(impl AnyAtom for $boxed {
205 fn from_any(any: Any) -> Option<Self> {
206 match any {
207 Any::$boxed(boxed) => Some(*boxed),
208 _ => None,
209 }
210 }
211
212 fn from_any_ref(any: &Any) -> Option<&Self> {
213 match any {
214 Any::$boxed(boxed) => Some(boxed),
215 _ => None,
216 }
217 }
218
219 fn from_any_mut(any: &mut Any) -> Option<&mut Self> {
220 match any {
221 Any::$boxed(boxed) => Some(boxed),
222 _ => None,
223 }
224 }
225
226 fn into_any(self) -> Any {
227 Any::$boxed(Box::new(self))
228 }
229 })*
230 };
231}
232
233any! {
234 basic: [
235 Ftyp,
236 Styp,
237 Meta,
238 Hdlr,
239 Pitm,
240 Iloc,
241 Iinf,
242 Iprp,
243 Ipco,
244 Auxc,
245 Clap,
246 Imir,
247 Irot,
248 Iscl,
249 Ispe,
250 Pixi,
251 Rref,
252 Ipma,
253 Iref,
254 Idat,
255 Ilst,
256 Covr,
257 Desc,
258 Tool, Name,
260 Year,
261 Moov,
262 Mvhd,
263 Udta,
264 Cprt,
265 Kind,
266 Skip,
267 Tkhd,
269 Mdia,
270 Mdhd,
271 Minf,
272 Stbl,
273 Stsd,
274 Avc1,
275 Avcc,
276 Btrt,
277 Ccst,
278 Colr,
279 Pasp,
280 Taic,
281 Fiel,
282 Hev1, Hvc1,
283 Hvcc,
284 Mp4a,
285 Esds,
286 Tx3g,
287 Ftab,
288 Vp08, Vp09,
289 VpcC,
290 Av01,
291 Av1c,
292 Opus,
293 Dops,
294 Uncv,
295 Cmpd,
296 UncC,
297 Flac,
298 Dfla,
299 Ac3,
300 Ac3SpecificBox,
301 Eac3,
302 Ec3SpecificBox,
303 Sowt, Twos, Lpcm, Ipcm, Fpcm, In24, In32, Fl32, Fl64, S16l,
304 PcmC,
305 Chnl,
306 Stts,
307 Stsc,
308 Stsz,
309 Stss,
310 Stco,
311 Co64,
312 Cslg,
313 Ctts,
314 Sbgp,
315 Sgpd,
316 Subs,
317 Saio,
318 Saiz,
319 Dinf,
320 Dref,
321 Nmhd,
322 Smhd,
323 Sthd,
324 Vmhd,
325 Edts,
326 Elst,
327 Mvex,
328 Mehd,
329 Trex,
330 Emsg,
331 Moof,
332 Mfhd,
333 Traf,
334 Tfhd,
335 Tfdt,
336 Trun,
337 Senc,
338 Mdat,
339 Free,
340 Sidx,
341 Prft,
342 Mfra,
343 Tfra,
344 Mfro,
345 ],
346 boxed: [
347 Trak,
348 ]
349}
350
351impl ReadFrom for Any {
352 fn read_from<R: Read>(r: &mut R) -> Result<Self> {
353 <Option<Any> as ReadFrom>::read_from(r)?.ok_or(Error::UnexpectedEof)
354 }
355}
356
357impl ReadFrom for Option<Any> {
358 fn read_from<R: Read>(r: &mut R) -> Result<Self> {
359 let header = match <Option<Header> as ReadFrom>::read_from(r)? {
360 Some(header) => header,
361 None => return Ok(None),
362 };
363
364 let body = &mut header.read_body(r)?;
365 Ok(Some(Any::decode_atom(&header, body)?))
366 }
367}
368
369impl ReadAtom for Any {
370 fn read_atom<R: Read>(header: &Header, r: &mut R) -> Result<Self> {
371 let body = &mut header.read_body(r)?;
372 Any::decode_atom(header, body)
373 }
374}