object_rainbow/
error.rs

1#[macro_export]
2/// Construct [`Error::Parse`].
3macro_rules! error_parse {
4    ($($t:tt)*) => {
5        $crate::Error::Parse($crate::anyhow!($($t)*))
6    };
7}
8
9#[macro_export]
10/// Construct [`Error::Fetch`].
11macro_rules! error_fetch {
12    ($($t:tt)*) => {
13        $crate::Error::Fetch($crate::anyhow!($($t)*))
14    };
15}
16
17/// Errors encountered during fetching an object. Mostly related to parsing.
18#[derive(Debug, thiserror::Error)]
19#[non_exhaustive]
20pub enum Error {
21    /// Arbitrary parsing error.
22    #[error(transparent)]
23    Parse(anyhow::Error),
24    /// Arbitrary fetching error.
25    #[error(transparent)]
26    Fetch(anyhow::Error),
27    #[error(transparent)]
28    Io(#[from] std::io::Error),
29    /// Data left after an [`Inline`] got parsed.
30    #[error("extra input left")]
31    ExtraInputLeft,
32    /// EOF.
33    #[error("end of input")]
34    EndOfInput,
35    /// Overran [`PointInput`]'s [`Address`] vector.
36    #[error("address index out of bounds")]
37    AddressOutOfBounds,
38    /// [`Address::hash`] doesn't match what [`Resolve`] returned.
39    #[error("hash resolution mismatch")]
40    ResolutionMismatch,
41    /// [`FullHash::full_hash`] doesn't match [`Singular::hash`].
42    #[error("full hash mismatch")]
43    FullHashMismatch,
44    /// Discriminant out of range for an [`Enum`].
45    #[error("discriminant overflow")]
46    DiscriminantOverflow,
47    /// Unepxected zero for a non-zero value.
48    #[error("zero")]
49    Zero,
50    /// Value out of bounds for a certain type.
51    #[error("out of bounds")]
52    OutOfBounds,
53    /// Current architecture (32-bit) is unable to handle lengths of this size.
54    #[error("length out of bounds")]
55    UnsupportedLength,
56    /// Not UTF-8.
57    #[error(transparent)]
58    Utf8(#[from] std::string::FromUtf8Error),
59    /// [`Resolve::extension`] (or related things) were unable to resolve the extension.
60    #[error("unknown extension")]
61    UnknownExtension,
62    /// Extension type didn't match what we asked for. This might be turned into panic later.
63    #[error("wrong extension type")]
64    ExtensionType,
65    #[error("not implemented")]
66    Unimplemented,
67    #[error("hash not found in the resolve")]
68    HashNotFound,
69}
70
71impl Error {
72    /// Construct [`Error::Parse`] from another error.
73    pub fn parse(e: impl Into<anyhow::Error>) -> Self {
74        Self::Parse(e.into())
75    }
76
77    /// Construct [`Error::Fetch`] from another error.
78    pub fn fetch(e: impl Into<anyhow::Error>) -> Self {
79        Self::Fetch(e.into())
80    }
81
82    pub fn io(e: impl Into<std::io::Error>) -> Self {
83        e.into().into()
84    }
85
86    fn io_kind(&self) -> std::io::ErrorKind {
87        use std::io::ErrorKind;
88        match self {
89            Error::Parse(_) => ErrorKind::InvalidData,
90            Error::Fetch(_) => ErrorKind::Other,
91            Error::Io(e) => e.kind(),
92            Error::ExtraInputLeft => ErrorKind::InvalidData,
93            Error::EndOfInput => ErrorKind::UnexpectedEof,
94            Error::AddressOutOfBounds => ErrorKind::Other,
95            Error::ResolutionMismatch => ErrorKind::InvalidData,
96            Error::FullHashMismatch => ErrorKind::InvalidData,
97            Error::DiscriminantOverflow => ErrorKind::InvalidData,
98            Error::Zero => ErrorKind::InvalidData,
99            Error::OutOfBounds => ErrorKind::InvalidData,
100            Error::UnsupportedLength => ErrorKind::FileTooLarge,
101            Error::Utf8(_) => ErrorKind::InvalidData,
102            Error::UnknownExtension => ErrorKind::Other,
103            Error::ExtensionType => ErrorKind::Other,
104            Error::Unimplemented => ErrorKind::Unsupported,
105            Error::HashNotFound => ErrorKind::NotFound,
106        }
107    }
108}
109
110impl From<Error> for std::io::Error {
111    fn from(value: Error) -> Self {
112        match value {
113            Error::Io(e) => e,
114            e => Self::new(e.io_kind(), e),
115        }
116    }
117}
118
119pub type Result<T> = std::result::Result<T, Error>;