From 94a01065226c273316f05b0c1145876bb9d809aa Mon Sep 17 00:00:00 2001 From: Max Wase Date: Fri, 15 May 2026 16:36:56 +0300 Subject: [PATCH 1/2] Add Ok generic to MainResult --- .gitignore | 3 +++ src/main_result.rs | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ea8c4bf..4522df4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ /target +.claude/ +.agents/ +.codex \ No newline at end of file diff --git a/src/main_result.rs b/src/main_result.rs index e8d1ac7..f8404f2 100644 --- a/src/main_result.rs +++ b/src/main_result.rs @@ -7,7 +7,9 @@ use super::{Format, Formatted, OneLine}; /// /// The format strategy `F` defaults to [`OneLine`]; pass [`crate::Tree`] or a custom [`Format`] /// to change how the error is rendered when `main` returns `Err`. -pub type MainResult = core::result::Result<(), DisplaySwapDebug>>; +/// The success type `T` defaults to `()`; pass `ExitCode` or another type to return from `main`. +pub type MainResult = + core::result::Result>>; /// Wrapper that swaps an inner type's [`fmt::Debug`] and [`fmt::Display`] impls. /// @@ -111,4 +113,19 @@ mod tests { "One" ); } + + #[test] + fn test_main_result_with_exit_code() { + use std::process::ExitCode; + + fn main_with_error(err: bool) -> MainResult { + if err { + return Err(Error::One)?; + } + Ok(ExitCode::SUCCESS) + } + + assert_eq!(main_with_error(false).unwrap(), ExitCode::SUCCESS); + assert_eq!(main_with_error(true).unwrap_err().0.to_string(), "One"); + } } From 82aebca5f5d4928bf1d4a54f38dd67a8e25e100a Mon Sep 17 00:00:00 2001 From: Max Wase Date: Fri, 15 May 2026 16:39:53 +0300 Subject: [PATCH 2/2] Remove FormatOneLine type alias --- README.md | 2 +- src/lib.rs | 8 ++++---- src/main_result.rs | 2 +- src/oneline.rs | 10 +++------- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index da24792..190e391 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ println!("{}", my_error.formatted::()); // outer -> middle -> inner ```rust use errortools::{DisplaySwapDebug, Formatted, OneLine}; -pub type MainResult = Result<(), DisplaySwapDebug>>; +pub type MainResult = Result>>; ``` `DisplaySwapDebug` swaps the `Debug` and `Display` impls of its inner type, so when `main` prints the error via `Debug`, you actually get its `Display` output — formatted by the chosen strategy. `?` converts your error automatically via the blanket `From` impl. diff --git a/src/lib.rs b/src/lib.rs index a4e9889..f4dd328 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ mod oneline; mod tree; pub use main_result::{DisplaySwapDebug, MainResult}; -pub use oneline::{FormatOneLine, OneLine}; +pub use oneline::OneLine; pub use tree::{Tree, TreeIndent, TreeMarker}; /// A static strategy for formatting an error and its source chain. @@ -35,13 +35,13 @@ pub fn chain<'a>(error: &'a dyn Error) -> impl Iterator + /// A helper trait to format errors. pub trait FormatError { /// Formats the error in a single line concatenated by `: `. - fn one_line(&self) -> FormatOneLine<&Self> { - FormatOneLine::new(self) + fn one_line(&self) -> Formatted<&Self, OneLine> { + self.formatted::() } /// Formats the error as an indented tree of sources. fn tree(&self) -> Formatted<&Self, Tree> { - Formatted::new(self) + self.formatted::() } /// Formats the error using a custom [`Format`] strategy. diff --git a/src/main_result.rs b/src/main_result.rs index f8404f2..28b5e92 100644 --- a/src/main_result.rs +++ b/src/main_result.rs @@ -120,7 +120,7 @@ mod tests { fn main_with_error(err: bool) -> MainResult { if err { - return Err(Error::One)?; + Err(Error::One)?; } Ok(ExitCode::SUCCESS) } diff --git a/src/oneline.rs b/src/oneline.rs index a4c4515..8261cf4 100644 --- a/src/oneline.rs +++ b/src/oneline.rs @@ -2,7 +2,7 @@ use core::{error::Error, fmt}; use itertools::Itertools; -use crate::{Format, Formatted, chain}; +use crate::{Format, chain}; /// One-line format. Joins the error and its sources with `": "`. /// @@ -18,9 +18,6 @@ impl Format for OneLine { } } -/// One-line error wrapper. Alias for [`Formatted`]. -pub type FormatOneLine = Formatted; - #[cfg(test)] mod tests { use core::fmt; @@ -29,8 +26,7 @@ mod tests { use itertools::Itertools; use crate::{ - Format, FormatError, Formatted, chain, - oneline::FormatOneLine, + Format, FormatError, Formatted, OneLine, chain, tests::{Error, ErrorInner}, }; @@ -48,7 +44,7 @@ mod tests { let error = Error::One; assert_eq!(error.one_line().to_string(), "One"); assert_eq!(format!("{:?}", error.one_line()), "One"); - assert_eq!(FormatOneLine::new(Error::One).to_string(), "One"); + assert_eq!(Formatted::<_, OneLine>::new(Error::One).to_string(), "One"); let error = Error::Two(ErrorInner::One); assert_eq!(error.one_line().to_string(), "Two: One");