favicon_scraper/
error.rs

1use std::error::Error as StdError;
2use std::fmt::{Display, Formatter};
3
4macro_rules! impl_error {
5    ($($name: ident ($typ: ty)),*; $($simple_name: ident),*) => {
6        /// favicon-scraper's automatically generated Error type.
7        ///
8        /// If more fatal errors are introduced in the future, this type may expand.
9        /// Hence why it's marked as `non_exhaustive`.
10        #[non_exhaustive]
11        #[derive(Debug)]
12        pub enum Error {
13            $($simple_name,)*
14            $($name($typ),)*
15        }
16
17        $(
18            impl From<$typ> for Error {
19                fn from(value: $typ) -> Self {
20                    Error::$name(value)
21                }
22            }
23        )*
24
25        impl Display for Error {
26            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
27                match self {
28                    $(Error::$simple_name => write!(f, stringify!($simple_name)),)*
29                    $(Error::$name(v) => Display::fmt(v, f),)*
30                }
31            }
32        }
33
34        impl StdError for Error {}
35    };
36}
37
38impl_error!(
39    Reqwest(reqwest::Error);
40    UnsupportedURLScheme,
41    UnsupportedImageFormat
42);
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    type SendBox = Box<dyn StdError + Send + Sync>;
49
50    /// This test just needs to compile.
51    /// It always panics in practice so no valid `Error` needs to be constructed
52    /// Compiling this test will fail if `Error` isn't `Send + Sync`.
53    /// `Error` must be `Send + Sync` because I got fed up with `site_icons` not being `Send`.
54    #[test]
55    #[should_panic]
56    fn is_send_and_sync() {
57        let _: SendBox = (|| -> Box<Error> { panic!("Success") })(); // If this fails to compile, Error isn't Send + Sync
58    }
59}