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_as_ref()88 fn test_as_ref() {
89     let error = bail_error().unwrap_err();
90     let ref_dyn: &dyn StdError = error.as_ref();
91     assert_eq!("oh no!", ref_dyn.to_string());
92     let ref_dyn_send_sync: &(dyn StdError + Send + Sync) = error.as_ref();
93     assert_eq!("oh no!", ref_dyn_send_sync.to_string());
94 }
95 
96 #[test]
test_large_alignment()97 fn test_large_alignment() {
98     #[repr(align(64))]
99     #[derive(Debug)]
100     struct LargeAlignedError(&'static str);
101 
102     impl Display for LargeAlignedError {
103         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104             f.write_str(self.0)
105         }
106     }
107 
108     impl StdError for LargeAlignedError {}
109 
110     let error = Error::new(LargeAlignedError("oh no!"));
111     assert_eq!(
112         "oh no!",
113         error.downcast_ref::<LargeAlignedError>().unwrap().0
114     );
115 }
116 
117 #[test]
test_unsuccessful_downcast()118 fn test_unsuccessful_downcast() {
119     let mut error = bail_error().unwrap_err();
120     assert!(error.downcast_ref::<&str>().is_none());
121     assert!(error.downcast_mut::<&str>().is_none());
122     assert!(error.downcast::<&str>().is_err());
123 }
124