1 use std::error::Error as StdError;
2 use std::io;
3 use thiserror::Error;
4 
5 #[derive(Error, Debug)]
6 #[error("implicit source")]
7 pub struct ImplicitSource {
8     source: io::Error,
9 }
10 
11 #[derive(Error, Debug)]
12 #[error("explicit source")]
13 pub struct ExplicitSource {
14     source: String,
15     #[source]
16     io: io::Error,
17 }
18 
19 #[derive(Error, Debug)]
20 #[error("boxed source")]
21 pub struct BoxedSource {
22     #[source]
23     source: Box<dyn StdError + Send + 'static>,
24 }
25 
26 #[test]
test_implicit_source()27 fn test_implicit_source() {
28     let io = io::Error::new(io::ErrorKind::Other, "oh no!");
29     let error = ImplicitSource { source: io };
30     error.source().unwrap().downcast_ref::<io::Error>().unwrap();
31 }
32 
33 #[test]
test_explicit_source()34 fn test_explicit_source() {
35     let io = io::Error::new(io::ErrorKind::Other, "oh no!");
36     let error = ExplicitSource {
37         source: String::new(),
38         io,
39     };
40     error.source().unwrap().downcast_ref::<io::Error>().unwrap();
41 }
42 
43 #[test]
test_boxed_source()44 fn test_boxed_source() {
45     let source = Box::new(io::Error::new(io::ErrorKind::Other, "oh no!"));
46     let error = BoxedSource { source };
47     error.source().unwrap().downcast_ref::<io::Error>().unwrap();
48 }
49 
50 macro_rules! error_from_macro {
51     ($($variants:tt)*) => {
52         #[derive(Error)]
53         #[derive(Debug)]
54         pub enum MacroSource {
55             $($variants)*
56         }
57     }
58 }
59 
60 // Test that we generate impls with the proper hygiene
61 #[rustfmt::skip]
62 error_from_macro! {
63     #[error("Something")]
64     Variant(#[from] io::Error)
65 }
66