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