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