Skip to main content

gix_error/
test.rs

1use crate::Error;
2
3/// An error for test functions that accepts any error supported by a boxed standard error.
4///
5/// Unlike [`Error`], this type deliberately does not implement [`std::error::Error`]. This allows it to accept arbitrary
6/// errors via [`From`] without conflicting with the standard library's identity conversion.
7/// Its [`Debug`](std::fmt::Debug) output includes the complete error tree or chain and all captured caller locations.
8pub struct TestError(Error);
9
10/// A result type for test functions whose errors are reported through [`TestError`]'s complete diagnostics.
11pub type TestResult<T = ()> = std::result::Result<T, TestError>;
12
13impl<E> From<E> for TestError
14where
15    E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
16{
17    #[track_caller]
18    fn from(error: E) -> Self {
19        let error = error.into();
20        TestError(match error.downcast::<Error>() {
21            Ok(error) => *error,
22            Err(error) => Error::from_boxed(error),
23        })
24    }
25}
26
27impl From<TestError> for Error {
28    fn from(error: TestError) -> Self {
29        error.0
30    }
31}
32
33impl std::fmt::Debug for TestError {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        #[cfg(any(feature = "tree-error", not(feature = "auto-chain-error")))]
36        return write!(f, "{:?}", self.0.inner.frame());
37
38        #[cfg(all(feature = "auto-chain-error", not(feature = "tree-error")))]
39        {
40            let mut errors = self.0.iter_errors_with_locations();
41            if let Some(error) = errors.next() {
42                write!(f, "{error}")?;
43                let mut errors = errors.peekable();
44                if errors.peek().is_some() {
45                    write!(f, "\n\nCaused by:")?;
46                    for (index, error) in errors.enumerate() {
47                        write!(f, "\n    {index}: {error}")?;
48                    }
49                }
50            }
51            Ok(())
52        }
53    }
54}