simple_eyre/lib.rs
1//! This library provides a custom [`eyre::EyreHandler`] type for usage with [`eyre`] that provides
2//! a minimal error report with no additional context. Essentially the minimal implementation of an
3//! error reporter.
4//!
5//! ## Setup
6//!
7//! Add the following to your toml file:
8//!
9//! ```toml
10//! [dependencies]
11//! simple-eyre = "0.3"
12//! ```
13//!
14//! Then install the hook handler before constructing any `eyre::Report` types.
15//!
16//! # Example
17//!
18//! ```rust,should_panic
19//! use simple_eyre::eyre::{eyre, WrapErr, Report};
20//!
21//! fn main() -> Result<(), Report> {
22//! simple_eyre::install()?;
23//!
24//! let e: Report = eyre!("oh no this program is just bad!");
25//!
26//! Err(e).wrap_err("usage example successfully experienced a failure")
27//! }
28//! ```
29//!
30//! [`eyre::EyreHandler`]: https://docs.rs/eyre/*/eyre/trait.EyreHandler.html
31//! [`eyre`]: https://docs.rs/eyre
32#![doc(html_root_url = "https://docs.rs/simple-eyre/0.3.1")]
33#![warn(
34 missing_debug_implementations,
35 missing_docs,
36 missing_doc_code_examples,
37 rust_2018_idioms,
38 unreachable_pub,
39 bad_style,
40 const_err,
41 dead_code,
42 improper_ctypes,
43 non_shorthand_field_patterns,
44 no_mangle_generic_items,
45 overflowing_literals,
46 path_statements,
47 patterns_in_fns_without_body,
48 private_in_public,
49 unconditional_recursion,
50 unused,
51 unused_allocation,
52 unused_comparisons,
53 unused_parens,
54 while_true
55)]
56pub use eyre;
57#[doc(hidden)]
58pub use eyre::{Report, Result};
59
60use eyre::EyreHandler;
61use indenter::indented;
62use std::error::Error;
63
64/// A custom context type for minimal error reporting via `eyre`
65#[derive(Debug)]
66pub struct Handler;
67
68impl EyreHandler for Handler {
69 fn debug(
70 &self,
71 error: &(dyn Error + 'static),
72 f: &mut core::fmt::Formatter<'_>,
73 ) -> core::fmt::Result {
74 use core::fmt::Write as _;
75
76 if f.alternate() {
77 return core::fmt::Debug::fmt(error, f);
78 }
79
80 write!(f, "{}", error)?;
81
82 if let Some(cause) = error.source() {
83 write!(f, "\n\nCaused by:")?;
84
85 let multiple = cause.source().is_some();
86 let errors = std::iter::successors(Some(cause), |e| (*e).source());
87
88 for (n, error) in errors.enumerate() {
89 writeln!(f)?;
90
91 if multiple {
92 write!(indented(f).ind(n), "{}", error)?;
93 } else {
94 write!(indented(f), "{}", error)?;
95 }
96 }
97 }
98
99 Ok(())
100 }
101}
102
103/// Install the `simple-eyre` hook as the global error report hook.
104///
105/// # Details
106///
107/// This function must be called to enable the customization of `eyre::Report`
108/// provided by `simple-eyre`. This function should be called early, ideally
109/// before any errors could be encountered.
110///
111/// Only the first install will succeed. Calling this function after another
112/// report handler has been installed will cause an error. **Note**: This
113/// function _must_ be called before any `eyre::Report`s are constructed to
114/// prevent the default handler from being installed.
115pub fn install() -> Result<()> {
116 crate::eyre::set_hook(Box::new(move |_| Box::new(Handler)))?;
117
118 Ok(())
119}