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 Skip,
265 Tkhd,
267 Mdia,
268 Mdhd,
269 Minf,
270 Stbl,
271 Stsd,
272 Avc1,
273 Avcc,
274 Btrt,
275 Ccst,
276 Colr,
277 Pasp,
278 Taic,
279 Fiel,
280 Hev1, Hvc1,
281 Hvcc,
282 Mp4a,
283 Esds,
284 Tx3g,
285 Ftab,
286 Vp08, Vp09,
287 VpcC,
288 Av01,
289 Av1c,
290 Opus,
291 Dops,
292 Uncv,
293 Cmpd,
294 UncC,
295 Flac,
296 Dfla,
297 Ac3,
298 Ac3SpecificBox,
299 Eac3,
300 Ec3SpecificBox,
301 Sowt, Twos, Lpcm, Ipcm, Fpcm, In24, In32, Fl32, Fl64, S16l,
302 PcmC,
303 Chnl,
304 Stts,
305 Stsc,
306 Stsz,
307 Stss,
308 Stco,
309 Co64,
310 Cslg,
311 Ctts,
312 Sbgp,
313 Sgpd,
314 Subs,
315 Saio,
316 Saiz,
317 Dinf,
318 Dref,
319 Smhd,
320 Vmhd,
321 Edts,
322 Elst,
323 Mvex,
324 Mehd,
325 Trex,
326 Emsg,
327 Moof,
328 Mfhd,
329 Traf,
330 Tfhd,
331 Tfdt,
332 Trun,
333 Senc,
334 Mdat,
335 Free,
336 Sidx,
337 Prft,
338 Mfra,
339 Tfra,
340 Mfro,
341 ],
342 boxed: [
343 Trak,
344 ]
345}
346
347impl ReadFrom for Any {
348 fn read_from<R: Read>(r: &mut R) -> Result<Self> {
349 <Option<Any> as ReadFrom>::read_from(r)?.ok_or(Error::UnexpectedEof)
350 }
351}
352
353impl ReadFrom for Option<Any> {
354 fn read_from<R: Read>(r: &mut R) -> Result<Self> {
355 let header = match <Option<Header> as ReadFrom>::read_from(r)? {
356 Some(header) => header,
357 None => return Ok(None),
358 };
359
360 let body = &mut header.read_body(r)?;
361 Ok(Some(Any::decode_atom(&header, body)?))
362 }
363}
364
365impl ReadAtom for Any {
366 fn read_atom<R: Read>(header: &Header, r: &mut R) -> Result<Self> {
367 let body = &mut header.read_body(r)?;
368 Any::decode_atom(header, body)
369 }
370}