error_rail/traits/
with_error.rs

1/// Abstraction over types that carry an error variant which can be remapped.
2///
3/// This trait provides a generic interface for types that contain both success and error cases,
4/// allowing transformation of the error type while preserving the success value.
5///
6/// # Type Parameters
7///
8/// * `E` - The current error type contained in the implementor
9///
10/// # Associated Types
11///
12/// * `Success` - The success value type when no error is present
13/// * `ErrorOutput<G>` - The output type after mapping the error to type `G`
14///
15/// # Examples
16///
17/// ```
18/// use error_rail::traits::WithError;
19///
20/// let result: Result<i32, &str> = Err("original error");
21/// let mapped = result.fmap_error(|e| format!("Error: {}", e));
22/// assert_eq!(mapped, Err("Error: original error".to_string()));
23/// ```
24pub trait WithError<E> {
25    type Success;
26
27    type ErrorOutput<G>;
28
29    /// Maps the error value using `f`, producing a new container with error type `G`.
30    ///
31    /// This operation leaves the success case untouched and only transforms the error.
32    ///
33    /// # Arguments
34    ///
35    /// * `f` - A function that transforms the error from type `E` to type `G`
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use error_rail::traits::WithError;
41    ///
42    /// let result: Result<i32, u32> = Err(404);
43    /// let mapped = result.fmap_error(|code| format!("HTTP {}", code));
44    /// assert_eq!(mapped, Err("HTTP 404".to_string()));
45    /// ```
46    fn fmap_error<F, G>(self, f: F) -> Self::ErrorOutput<G>
47    where
48        F: Fn(E) -> G;
49
50    /// Converts the container into a `Result`.
51    ///
52    /// For types that are already `Result`, this is a no-op.
53    /// For other types, this extracts the success/error into standard Result form.
54    ///
55    /// # Examples
56    ///
57    /// ```
58    /// use error_rail::traits::WithError;
59    ///
60    /// let result: Result<i32, &str> = Ok(42);
61    /// assert_eq!(result.to_result(), Ok(42));
62    /// ```
63    fn to_result(self) -> Result<Self::Success, E>;
64}
65
66impl<T, E> WithError<E> for Result<T, E> {
67    type Success = T;
68    type ErrorOutput<G> = Result<T, G>;
69
70    fn fmap_error<F, G>(self, f: F) -> Self::ErrorOutput<G>
71    where
72        F: FnOnce(E) -> G,
73    {
74        match self {
75            Ok(t) => Ok(t),
76            Err(e) => Err(f(e)),
77        }
78    }
79
80    fn to_result(self) -> Result<Self::Success, E> {
81        self
82    }
83}