error_rail/traits/
into_error_context.rs

1//! Trait for converting types into structured error context.
2//!
3//! This trait provides a unified interface for types that can be converted into
4//! [`ErrorContext`], enabling flexible context attachment in error handling pipelines.
5//!
6//! # Implementations
7//!
8//! The trait is implemented for common types:
9//! - `String` - Converts to `ErrorContext::Message`
10//! - `&str` - Converts to `ErrorContext::Message`
11//! - `ErrorContext` - Identity conversion (no-op)
12//!
13//! # Examples
14//!
15//! ```
16//! use error_rail::{traits::IntoErrorContext, ErrorContext};
17//!
18//! let ctx1 = "simple message".into_error_context();
19//! let ctx2 = String::from("owned message").into_error_context();
20//! let ctx3 = ErrorContext::tag("network").into_error_context();
21//!
22//! assert_eq!(ctx1.message(), "simple message");
23//! assert_eq!(ctx2.message(), "owned message");
24//! assert!(ctx3.message().contains("[network]"));
25//! ```
26use crate::types::alloc_type::{Cow, String};
27use crate::types::error_context::ErrorContext;
28
29/// Converts a type into an [`ErrorContext`] for error annotation.
30///
31/// This trait is used throughout the error handling pipeline to accept
32/// flexible context types when building composable errors.
33///
34/// # Implementing for Custom Types
35///
36/// If you need to use a custom type as error context, you have two options:
37///
38/// 1. Use the [`impl_error_context!`](crate::impl_error_context) macro for types implementing `Display`:
39///    ```ignore
40///    impl_error_context!(MyCustomError);
41///    ```
42///
43/// 2. Implement the trait manually:
44///    ```
45///    use error_rail::{traits::IntoErrorContext, ErrorContext};
46///
47///    struct MyContext { user_id: u64 }
48///
49///    impl IntoErrorContext for MyContext {
50///        fn into_error_context(self) -> ErrorContext {
51///            ErrorContext::metadata("user_id", self.user_id.to_string())
52///        }
53///    }
54///    ```
55#[diagnostic::on_unimplemented(
56    message = "`{Self}` cannot be used as error context",
57    label = "this type does not implement `IntoErrorContext`",
58    note = "implement `IntoErrorContext` manually or use `impl_error_context!({Self})` macro",
59    note = "see: https://docs.rs/error-rail/latest/error_rail/macro.impl_error_context.html"
60)]
61pub trait IntoErrorContext {
62    /// Converts `self` into an [`ErrorContext`].
63    fn into_error_context(self) -> ErrorContext;
64}
65
66impl IntoErrorContext for String {
67    /// Converts an owned `String` into a message context.
68    #[inline]
69    fn into_error_context(self) -> ErrorContext {
70        ErrorContext::new(self)
71    }
72}
73
74impl IntoErrorContext for &'static str {
75    /// Converts a static string slice into a message context.
76    #[inline]
77    fn into_error_context(self) -> ErrorContext {
78        ErrorContext::new(self)
79    }
80}
81
82impl IntoErrorContext for Cow<'static, str> {
83    /// Converts a Cow string into a message context.
84    #[inline]
85    fn into_error_context(self) -> ErrorContext {
86        ErrorContext::new(self)
87    }
88}
89
90impl IntoErrorContext for ErrorContext {
91    /// Identity conversion for `ErrorContext` (no-op).
92    #[inline]
93    fn into_error_context(self) -> ErrorContext {
94        self
95    }
96}