1use alloc::boxed::Box;
2use core::{error::Error, fmt};
3
4use crate::Report;
5
6pub type ReportProgramExit = Result<(), ProgramReport>;
8
9pub struct ProgramReport(Box<dyn Error + 'static>);
11impl<E: Error + 'static> From<E> for ProgramReport {
12 fn from(value: E) -> Self {
13 Self(Box::new(value))
14 }
15}
16impl fmt::Debug for ProgramReport {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 write!(f, "{self}")
19 }
20}
21impl fmt::Display for ProgramReport {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 let report = Report::new(self.0.as_ref());
24
25 #[cfg(feature = "std")]
26 let current_exe = std::env::current_exe().ok();
27 #[cfg(feature = "std")]
28 let current_exe_file_name = current_exe.as_ref().and_then(|path| path.file_name());
29 #[cfg(feature = "std")]
30 let current_exe_name = current_exe_file_name
31 .as_ref()
32 .and_then(|name| name.to_str());
33 #[cfg(feature = "std")]
34 let exe = current_exe_name.unwrap_or("the program");
35 #[cfg(not(feature = "std"))]
36 let exe = "the program";
37
38 writeln!(f, "{exe} exited unsuccessfully")?;
39 write!(f, "{report}")
40 }
41}