mp4ameta/error.rs
1use std::borrow::Cow;
2use std::{error, fmt, io};
3
4use crate::Fourcc;
5
6/// Type alias for the result of tag operations.
7pub type Result<T> = std::result::Result<T, Error>;
8
9/// Kinds of errors that may occur while performing metadata operations.
10#[derive(Debug)]
11pub enum ErrorKind {
12 /// An atom could not be found. Contains the atom's identifier.
13 AtomNotFound(Fourcc),
14 /// A descriptor could not be found. Contains the descriptor's tag.
15 DescriptorNotFound(u8),
16 /// No filetype (`ftyp`) atom, which indicates na MPEG-4 file, could be found.
17 NoFtyp,
18 /// The size of an atom is smaller than its header, or otherwise unsound.
19 InvalidAtomSize,
20 /// The content of an atom suggests another length than its header.
21 SizeMismatch,
22 /// The header of an atom specifies a size that either exceeds the parent atom or the file.
23 AtomSizeOutOfBounds,
24 /// The sample table atom (`stbl`) contains inconsistent data.
25 InvalidSampleTable,
26 /// The [`ChannelConfig`] code is unknown. Contains the unknown code.
27 ///
28 /// [`ChannelConfig`]: crate::ChannelConfig
29 UnknownChannelConfig(u8),
30 /// The [`MediaType`] code is unknown. Contains the unknown code.
31 ///
32 /// [`MediaType`]: crate::MediaType
33 UnknownMediaType(u8),
34 /// The [`SampleRate`] index is unknown. Contains the unknown index.
35 ///
36 /// [`SampleRate`]: crate::SampleRate
37 UnknownSampleRate(u8),
38 /// Either the version byte of an atom or a descriptor is unknown. Contains the unknown version.
39 UnknownVersion(u8),
40 /// An invalid utf-8 string was found.
41 Utf8StringDecoding,
42 /// An invalid utf-16 string was found.
43 Utf16StringDecoding,
44 /// An IO error has occurred.
45 Io(io::Error),
46}
47
48/// Any error that may occur while performing metadata operations.
49pub struct Error {
50 /// The kind of error that occurred.
51 pub kind: ErrorKind,
52 /// A human readable string describing the error.
53 pub description: Cow<'static, str>,
54}
55
56impl Error {
57 pub fn new(kind: ErrorKind, description: impl Into<Cow<'static, str>>) -> Error {
58 Error { kind, description: description.into() }
59 }
60}
61
62impl error::Error for Error {
63 fn cause(&self) -> Option<&dyn error::Error> {
64 match self.kind {
65 ErrorKind::Io(ref err) => Some(err),
66 _ => None,
67 }
68 }
69}
70
71impl From<io::Error> for Error {
72 fn from(err: io::Error) -> Error {
73 let description = format!("IO error: {err}");
74 Error::new(ErrorKind::Io(err), description)
75 }
76}
77
78impl fmt::Debug for Error {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 if self.description.is_empty() {
81 write!(f, "{:?}", self.kind)
82 } else {
83 write!(f, "{}:\n{:?}", self.description, self.kind)
84 }
85 }
86}
87
88impl fmt::Display for Error {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 if self.description.is_empty() {
91 write!(f, "{:?}", self.kind)
92 } else {
93 write!(f, "{}:\n{:?}", self.description, self.kind)
94 }
95 }
96}