pahs_snafu/
lib.rs

1//! Helpers for using pahs together with snafu
2
3#![deny(rust_2018_idioms)]
4#![warn(missing_docs)]
5#![warn(clippy::missing_inline_in_public_items)]
6
7use pahs::Progress;
8
9/// Extension trait for pahs' [`Progress`](pahs::Progress) type for integration with snafu.
10pub trait ProgressSnafuExt<P, T, E> {
11    /// Maps the error of the progress to a snafu error, with the previous error as the source.
12    ///
13    /// `context_fn` has to be a function that returns the context selector of that error.
14    fn snafu<C, F, E2>(self, context_fn: F) -> Progress<P, T, E2>
15    where
16        P: Clone,
17        C: snafu::IntoError<E2, Source = E>,
18        F: FnOnce(P) -> C,
19        E2: std::error::Error + snafu::ErrorCompat;
20
21    /// Maps the error of the progress to a snafu leaf error.
22    ///
23    /// `context_fn` has to be a function that returns the context selector of that leaf error.
24    fn into_snafu_leaf<C, F, E2>(self, context_fn: F) -> Progress<P, T, E2>
25    where
26        P: Clone,
27        C: snafu::IntoError<E2, Source = snafu::NoneError>,
28        F: FnOnce(E, P) -> C,
29        E2: std::error::Error + snafu::ErrorCompat;
30
31    /// Replaces the error of the progress with a snafu leaf error.
32    ///
33    /// `context_fn` has to be a function that returns the context selector of that leaf error.
34    ///
35    /// If you get an error because `E` cannot be inferred, try using
36    /// [`into_snafu_leaf`](Progress::into_snafu_leaf) instead to specify the type of the error
37    /// (first `context_fn` parameter).
38    fn snafu_leaf<C, F, E2>(self, context_fn: F) -> Progress<P, T, E2>
39    where
40        P: Clone,
41        C: snafu::IntoError<E2, Source = snafu::NoneError>,
42        F: FnOnce(P) -> C,
43        E2: std::error::Error + snafu::ErrorCompat;
44}
45
46impl<P, T, E> ProgressSnafuExt<P, T, E> for Progress<P, T, E> {
47    #[inline]
48    fn snafu<C, F, E2>(self, context_fn: F) -> Progress<P, T, E2>
49    where
50        P: Clone,
51        C: snafu::IntoError<E2, Source = E>,
52        F: FnOnce(P) -> C,
53        E2: std::error::Error + snafu::ErrorCompat,
54    {
55        self.map_err_with_pos(|e, pos| context_fn(pos).into_error(e))
56    }
57
58    #[inline]
59    fn into_snafu_leaf<C, F, E2>(self, context_fn: F) -> Progress<P, T, E2>
60    where
61        P: Clone,
62        C: snafu::IntoError<E2, Source = snafu::NoneError>,
63        F: FnOnce(E, P) -> C,
64        E2: std::error::Error + snafu::ErrorCompat,
65    {
66        self.map_err_with_pos(|e, pos| context_fn(e, pos).into_error(snafu::NoneError))
67    }
68
69    #[inline]
70    fn snafu_leaf<C, F, E2>(self, context_fn: F) -> Progress<P, T, E2>
71    where
72        P: Clone,
73        C: snafu::IntoError<E2, Source = snafu::NoneError>,
74        F: FnOnce(P) -> C,
75        E2: std::error::Error + snafu::ErrorCompat,
76    {
77        self.map_err_with_pos(|_, pos| context_fn(pos).into_error(snafu::NoneError))
78    }
79}