1 #![allow(clippy::wildcard_imports)]
2 
3 mod common;
4 mod drop;
5 
6 use self::common::*;
7 use self::drop::{DetectDrop, Flag};
8 use anyhow::Error;
9 use std::error::Error as StdError;
10 use std::fmt::{self, Display};
11 use std::io;
12 
13 #[test]
test_downcast()14 fn test_downcast() {
15     assert_eq!(
16         "oh no!",
17         bail_literal().unwrap_err().downcast::<&str>().unwrap(),
18     );
19     assert_eq!(
20         "oh no!",
21         bail_fmt().unwrap_err().downcast::<String>().unwrap(),
22     );
23     assert_eq!(
24         "oh no!",
25         bail_error()
26             .unwrap_err()
27             .downcast::<io::Error>()
28             .unwrap()
29             .to_string(),
30     );
31 }
32 
33 #[test]
test_downcast_ref()34 fn test_downcast_ref() {
35     assert_eq!(
36         "oh no!",
37         *bail_literal().unwrap_err().downcast_ref::<&str>().unwrap(),
38     );
39     assert_eq!(
40         "oh no!",
41         bail_fmt().unwrap_err().downcast_ref::<String>().unwrap(),
42     );
43     assert_eq!(
44         "oh no!",
45         bail_error()
46             .unwrap_err()
47             .downcast_ref::<io::Error>()
48             .unwrap()
49             .to_string(),
50     );
51 }
52 
53 #[test]
test_downcast_mut()54 fn test_downcast_mut() {
55     assert_eq!(
56         "oh no!",
57         *bail_literal().unwrap_err().downcast_mut::<&str>().unwrap(),
58     );
59     assert_eq!(
60         "oh no!",
61         bail_fmt().unwrap_err().downcast_mut::<String>().unwrap(),
62     );
63     assert_eq!(
64         "oh no!",
65         bail_error()
66             .unwrap_err()
67             .downcast_mut::<io::Error>()
68             .unwrap()
69             .to_string(),
70     );
71 
72     let mut bailed = bail_fmt().unwrap_err();
73     *bailed.downcast_mut::<String>().unwrap() = "clobber".to_string();
74     assert_eq!(bailed.downcast_ref::<String>().unwrap(), "clobber");
75     assert_eq!(bailed.downcast_mut::<String>().unwrap(), "clobber");
76     assert_eq!(bailed.downcast::<String>().unwrap(), "clobber");
77 }
78 
79 #[test]
test_drop()80 fn test_drop() {
81     let has_dropped = Flag::new();
82     let error = Error::new(DetectDrop::new(&has_dropped));
83     drop(error.downcast::<DetectDrop>().unwrap());
84     assert!(has_dropped.get());
85 }
86 
87 #[test]
test_large_alignment()88 fn test_large_alignment() {
89     #[repr(align(64))]
90     #[derive(Debug)]
91     struct LargeAlignedError(&'static str);
92 
93     impl Display for LargeAlignedError {
94         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95             f.write_str(self.0)
96         }
97     }
98 
99     impl StdError for LargeAlignedError {}
100 
101     let error = Error::new(LargeAlignedError("oh no!"));
102     assert_eq!(
103         "oh no!",
104         error.downcast_ref::<LargeAlignedError>().unwrap().0
105     );
106 }
107 
108 #[test]
test_unsuccessful_downcast()109 fn test_unsuccessful_downcast() {
110     let mut error = bail_error().unwrap_err();
111     assert!(error.downcast_ref::<&str>().is_none());
112     assert!(error.downcast_mut::<&str>().is_none());
113     assert!(error.downcast::<&str>().is_err());
114 }
115