mcpkit_core/error/context.rs
1//! Context extension trait for error handling.
2//!
3//! This module provides `anyhow`-style context methods while
4//! preserving the typed error system.
5
6use super::types::McpError;
7
8/// Extension trait for adding context to `Result` types.
9///
10/// This provides `anyhow`-style context methods while preserving the
11/// typed error system.
12///
13/// # Example
14///
15/// ```rust
16/// use mcpkit_core::error::{McpError, McpResultExt};
17///
18/// fn process() -> Result<(), McpError> {
19/// let result: Result<(), McpError> = Err(McpError::internal("oops"));
20/// result.context("Failed to process data")?;
21/// Ok(())
22/// }
23/// ```
24pub trait McpResultExt<T> {
25 /// Add context to an error.
26 fn context<C: Into<String>>(self, context: C) -> Result<T, McpError>;
27
28 /// Add context lazily (only evaluated on error).
29 fn with_context<C, F>(self, f: F) -> Result<T, McpError>
30 where
31 C: Into<String>,
32 F: FnOnce() -> C;
33}
34
35impl<T> McpResultExt<T> for Result<T, McpError> {
36 fn context<C: Into<String>>(self, context: C) -> Self {
37 self.map_err(|e| McpError::WithContext {
38 context: context.into(),
39 source: Box::new(e),
40 })
41 }
42
43 fn with_context<C, F>(self, f: F) -> Self
44 where
45 C: Into<String>,
46 F: FnOnce() -> C,
47 {
48 self.map_err(|e| McpError::WithContext {
49 context: f().into(),
50 source: Box::new(e),
51 })
52 }
53}