error_rail/traits/error_category.rs
1use crate::traits::*;
2
3/// Trait for types that can lift values and handle errors in a functorial way.
4///
5/// This trait provides a categorical abstraction over error-handling types,
6/// allowing them to:
7/// - Lift pure values into the error context (`lift`)
8/// - Construct error cases from error values (`handle_error`)
9///
10/// # Type Parameters
11///
12/// * `E` - The error type that this category handles
13///
14/// # Associated Types
15///
16/// * `ErrorFunctor<T>` - The functor type that wraps values of type `T` with error handling
17///
18/// # Examples
19///
20/// ```
21/// use error_rail::traits::ErrorCategory;
22///
23/// let success: Result<i32, &str> = <Result<(), &str>>::lift(42);
24/// assert_eq!(success, Ok(42));
25///
26/// let failure: Result<i32, &str> = <Result<(), &str>>::handle_error("error");
27/// assert_eq!(failure, Err("error"));
28/// ```
29pub trait ErrorCategory<E> {
30 /// The functor type that wraps values with error handling capability.
31 type ErrorFunctor<T>: WithError<E>;
32
33 /// Lifts a pure value into the error functor context.
34 ///
35 /// # Arguments
36 ///
37 /// * `value` - The value to lift into the error context
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// use error_rail::traits::ErrorCategory;
43 ///
44 /// let result: Result<i32, &str> = <Result<(), &str>>::lift(42);
45 /// assert_eq!(result, Ok(42));
46 /// ```
47 fn lift<T>(value: T) -> Self::ErrorFunctor<T>;
48
49 /// Constructs an error case from an error value.
50 ///
51 /// # Arguments
52 ///
53 /// * `error` - The error value to wrap
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use error_rail::traits::ErrorCategory;
59 ///
60 /// let result: Result<i32, &str> = <Result<(), &str>>::handle_error("failed");
61 /// assert_eq!(result, Err("failed"));
62 /// ```
63 fn handle_error<T>(error: E) -> Self::ErrorFunctor<T>;
64}
65
66/// Implementation of `ErrorCategory` for `Result` types.
67///
68/// This allows `Result<(), E>` to act as an error category, where:
69/// - `lift` creates `Ok` values
70/// - `handle_error` creates `Err` values
71///
72/// # Examples
73///
74/// ```
75/// use error_rail::traits::ErrorCategory;
76///
77/// let ok_value: Result<i32, String> = <Result<(), String>>::lift(100);
78/// assert_eq!(ok_value, Ok(100));
79///
80/// let err_value: Result<i32, String> = <Result<(), String>>::handle_error("error".to_string());
81/// assert_eq!(err_value, Err("error".to_string()));
82/// ```
83impl<E> ErrorCategory<E> for Result<(), E> {
84 type ErrorFunctor<T> = Result<T, E>;
85
86 #[inline]
87 fn lift<T>(value: T) -> Result<T, E> {
88 Ok(value)
89 }
90
91 #[inline]
92 fn handle_error<T>(error: E) -> Result<T, E> {
93 Err(error)
94 }
95}