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