1 use super::{const_io_error, Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage};
2 use crate::assert_matches::assert_matches;
5 use crate::mem::size_of;
6 use crate::sys::decode_error_kind;
7 use crate::sys::os::error_string;
11 assert!(size_of::<Error>() <= size_of::<[usize; 2]>());
15 fn test_debug_error() {
17 let msg = error_string(code);
18 let kind = decode_error_kind(code);
20 repr: Repr::new_custom(Box::new(Custom {
21 kind: ErrorKind::InvalidInput,
22 error: Box::new(Error { repr: super::Repr::new_os(code) }),
25 let expected = format!(
36 assert_eq!(format!("{err:?}"), expected);
40 fn test_downcasting() {
44 impl fmt::Display for TestError {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 impl error::Error for TestError {}
52 // we have to call all of these UFCS style right now since method
53 // resolution won't implicitly drop the Send+Sync bounds
54 let mut err = Error::new(ErrorKind::Other, TestError);
55 assert!(err.get_ref().unwrap().is::<TestError>());
56 assert_eq!("asdf", err.get_ref().unwrap().to_string());
57 assert!(err.get_mut().unwrap().is::<TestError>());
58 let extracted = err.into_inner().unwrap();
59 extracted.downcast::<TestError>().unwrap();
64 const E: Error = const_io_error!(ErrorKind::NotFound, "hello");
66 assert_eq!(E.kind(), ErrorKind::NotFound);
67 assert_eq!(E.to_string(), "hello");
68 assert!(format!("{E:?}").contains("\"hello\""));
69 assert!(format!("{E:?}").contains("NotFound"));
73 fn test_os_packing() {
74 for code in -20i32..20i32 {
75 let e = Error::from_raw_os_error(code);
76 assert_eq!(e.raw_os_error(), Some(code));
79 ErrorData::Os(c) if c == code,
85 fn test_errorkind_packing() {
86 assert_eq!(Error::from(ErrorKind::NotFound).kind(), ErrorKind::NotFound);
87 assert_eq!(Error::from(ErrorKind::PermissionDenied).kind(), ErrorKind::PermissionDenied);
88 assert_eq!(Error::from(ErrorKind::Uncategorized).kind(), ErrorKind::Uncategorized);
89 // Check that the innards look like what we want.
91 Error::from(ErrorKind::OutOfMemory).repr.data(),
92 ErrorData::Simple(ErrorKind::OutOfMemory),
97 fn test_simple_message_packing() {
98 use super::{ErrorKind::*, SimpleMessage};
99 macro_rules! check_simple_msg {
100 ($err:expr, $kind:ident, $msg:literal) => {{
102 // Check that the public api is right.
103 assert_eq!(e.kind(), $kind);
104 assert!(format!("{e:?}").contains($msg));
105 // and we got what we expected
108 ErrorData::SimpleMessage(SimpleMessage { kind: $kind, message: $msg })
113 let not_static = const_io_error!(Uncategorized, "not a constant!");
114 check_simple_msg!(not_static, Uncategorized, "not a constant!");
116 const CONST: Error = const_io_error!(NotFound, "definitely a constant!");
117 check_simple_msg!(CONST, NotFound, "definitely a constant!");
119 static STATIC: Error = const_io_error!(BrokenPipe, "a constant, sort of!");
120 check_simple_msg!(STATIC, BrokenPipe, "a constant, sort of!");
123 #[derive(Debug, PartialEq)]
125 impl error::Error for Bojji {}
126 impl fmt::Display for Bojji {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 write!(f, "ah! {:?}", self)
133 fn test_custom_error_packing() {
135 let test = Error::new(ErrorKind::Uncategorized, Bojji(true));
138 ErrorData::Custom(Custom {
139 kind: ErrorKind::Uncategorized,
141 }) if error.downcast_ref::<Bojji>().as_deref() == Some(&Bojji(true)),
148 impl fmt::Display for E {
149 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 impl error::Error for E {}
157 fn test_std_io_error_downcast() {
158 // Case 1: custom error, downcast succeeds
159 let io_error = Error::new(ErrorKind::Other, Bojji(true));
160 let e: Box<Bojji> = io_error.downcast().unwrap();
163 // Case 2: custom error, downcast fails
164 let io_error = Error::new(ErrorKind::Other, Bojji(true));
165 let io_error = io_error.downcast::<E>().unwrap_err();
167 // ensures that the custom error is intact
168 assert_eq!(ErrorKind::Other, io_error.kind());
169 let e: Box<Bojji> = io_error.downcast().unwrap();
174 let io_error = Error::from_raw_os_error(errno);
175 let io_error = io_error.downcast::<E>().unwrap_err();
177 assert_eq!(errno, io_error.raw_os_error().unwrap());
180 let kind = ErrorKind::OutOfMemory;
181 let io_error: Error = kind.into();
182 let io_error = io_error.downcast::<E>().unwrap_err();
184 assert_eq!(kind, io_error.kind());
186 // Case 5: simple message
187 const SIMPLE_MESSAGE: SimpleMessage =
188 SimpleMessage { kind: ErrorKind::Other, message: "simple message error test" };
189 let io_error = Error::from_static_message(&SIMPLE_MESSAGE);
190 let io_error = io_error.downcast::<E>().unwrap_err();
192 assert_eq!(SIMPLE_MESSAGE.kind, io_error.kind());
193 assert_eq!(SIMPLE_MESSAGE.message, &*format!("{io_error}"));