From 46b7f58e72671756d3462cfecc3c92d195c6ed37 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 28 Jul 2023 17:06:10 +0200 Subject: [PATCH] feat: add `annotate()` method to Context to just annotate the passed error with location data Signed-off-by: Harald Hoyer --- examples/example.rs | 9 +++++++-- src/lib.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/examples/example.rs b/examples/example.rs index c1d5702..82c073f 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -1,4 +1,4 @@ -use chainerror::prelude::v2::*; +use chainerror::Context as _; use std::error::Error; use std::fmt; use std::io; @@ -8,12 +8,17 @@ fn do_some_io() -> Result<(), Box> { Ok(()) } -fn func3() -> Result<(), Box> { +fn func4() -> Result<(), Box> { let filename = "foo.txt"; do_some_io().context(format!("Error reading '{}'", filename))?; Ok(()) } +fn func3() -> Result<(), Box> { + func4().annotate()?; + Ok(()) +} + chainerror::str_context!(Func2Error); fn func2() -> chainerror::Result<(), Func2Error> { diff --git a/src/lib.rs b/src/lib.rs index f15fd7d..372cef2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -216,6 +216,9 @@ pub trait Context>> { /// Decorate the error with a `kind` of type `T` and the source `Location` fn context(self, kind: T) -> std::result::Result>; + /// Decorate the error just with the source `Location` + fn annotate(self) -> std::result::Result>; + /// Decorate the `error` with a `kind` of type `T` produced with a `FnOnce(&error)` and the source `Location` fn map_context T>( self, @@ -223,6 +226,21 @@ pub trait Context>> { ) -> std::result::Result>; } +/// Convenience type to just decorate the error with the source `Location` +pub struct AnnotatedError(()); + +impl Display for AnnotatedError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "(passed error)") + } +} + +impl Debug for AnnotatedError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "(passed error)") + } +} + impl>> Context for std::result::Result { @@ -239,6 +257,19 @@ impl>> Context } } + #[track_caller] + #[inline] + fn annotate(self) -> std::result::Result> { + match self { + Ok(t) => Ok(t), + Err(error_cause) => Err(Error::new( + AnnotatedError(()), + Some(error_cause.into()), + Some(Location::caller().to_string()), + )), + } + } + #[track_caller] #[inline] fn map_context T>(