ts_error/
program_exit.rs

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