Skip to main content

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}