composite_error/
lib.rs

1//! Create a simple error enum that is a composite of other errors.
2//! ```rust
3//! # use composite_error::composite_error;
4//! composite_error! {
5//!     MyError {
6//!         IoError: std::io::Error,
7//!         Other: String,
8//!     }
9//! }
10//!
11//! let e = MyError::Other("This is an error".into());
12//! println!("{}", e);
13//! ```
14
15#[macro_export]
16macro_rules! composite_error {
17    ($name:ident { $($variant:ident: $error:ty,)* }) => {
18        enum $name {
19            $($variant($error)),*
20        }
21        
22        impl std::fmt::Display for $name {
23            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
24                let (variant, value) = match self {
25                    $(Self::$variant(e) => (stringify!($variant), e.to_string())),*
26                };
27
28                std::write!(f, "{}: {}", variant, value)
29            }
30        }
31
32        $(
33        impl std::convert::From<$error> for $name {
34            fn from(e: $error) -> Self {
35                Self::$variant(e)
36            }
37        }
38        )*
39    };
40    (#[derive($($derives:path),*)] $name:ident { $($variant:ident: $error:ty,)* }) => {
41        #[derive($($derives),*)]
42        enum $name {
43            $($variant($error)),*
44        }
45        
46        impl std::fmt::Display for $name {
47            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
48                let (variant, value) = match self {
49                    $(Self::$variant(e) => (stringify!($variant), e.to_string())),*
50                };
51
52                std::write!(f, "{}: {}", variant, value)
53            }
54        }
55
56        $(
57        impl std::convert::From<$error> for $name {
58            fn from(e: $error) -> Self {
59                Self::$variant(e)
60            }
61        }
62        )*
63    };
64}
65
66#[cfg(test)]
67mod tests {
68    #[test]
69    fn it_works() {
70        assert_eq!(2 + 2, 4);
71    }
72}