Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/target
.claude/
.agents/
.codex
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ println!("{}", my_error.formatted::<Arrow>()); // outer -> middle -> inner
```rust
use errortools::{DisplaySwapDebug, Formatted, OneLine};

pub type MainResult<E, F = OneLine> = Result<(), DisplaySwapDebug<Formatted<E, F>>>;
pub type MainResult<E, F = OneLine, T = ()> = Result<T, DisplaySwapDebug<Formatted<E, F>>>;
```

`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.
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -35,13 +35,13 @@ pub fn chain<'a>(error: &'a dyn Error) -> impl Iterator<Item = &'a dyn Error> +
/// 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::<OneLine>()
}

/// Formats the error as an indented tree of sources.
fn tree(&self) -> Formatted<&Self, Tree> {
Formatted::new(self)
self.formatted::<Tree>()
}

/// Formats the error using a custom [`Format`] strategy.
Expand Down
19 changes: 18 additions & 1 deletion src/main_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<E, F = OneLine> = core::result::Result<(), DisplaySwapDebug<Formatted<E, F>>>;
/// The success type `T` defaults to `()`; pass `ExitCode` or another type to return from `main`.
pub type MainResult<E, F = OneLine, T = ()> =
core::result::Result<T, DisplaySwapDebug<Formatted<E, F>>>;

/// Wrapper that swaps an inner type's [`fmt::Debug`] and [`fmt::Display`] impls.
///
Expand Down Expand Up @@ -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<Error, OneLine, ExitCode> {
if err {
Err(Error::One)?;
Comment thread
maxwase marked this conversation as resolved.
}
Ok(ExitCode::SUCCESS)
}

assert_eq!(main_with_error(false).unwrap(), ExitCode::SUCCESS);
assert_eq!(main_with_error(true).unwrap_err().0.to_string(), "One");
}
}
10 changes: 3 additions & 7 deletions src/oneline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 `": "`.
///
Expand All @@ -18,9 +18,6 @@ impl Format for OneLine {
}
}

/// One-line error wrapper. Alias for [`Formatted<E, OneLine>`].
pub type FormatOneLine<E> = Formatted<E, OneLine>;

#[cfg(test)]
mod tests {
use core::fmt;
Expand All @@ -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},
};

Expand All @@ -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");
Expand Down