turul_mcp_session_storage/
session_view.rs

1// SessionView trait for middleware access to sessions
2//!
3//! Minimal interface for middleware to access session state without depending on
4//! the concrete SessionContext implementation in turul-mcp-server.
5
6use async_trait::async_trait;
7use serde_json::Value;
8
9/// Minimal session interface for middleware access
10///
11/// This trait provides a read-write view of session state for middleware
12/// without exposing the full SessionContext implementation details.
13///
14/// # Silent Write Failures
15///
16/// **IMPORTANT**: `set_state` and `set_metadata` currently always return `Ok(())`.
17/// The underlying storage may log errors but does not propagate them to middleware.
18/// This design prevents middleware from blocking request processing due to storage issues.
19///
20/// # Example
21///
22/// ```rust,no_run
23/// use turul_mcp_session_storage::SessionView;
24/// use serde_json::json;
25///
26/// async fn middleware_example(session: &dyn SessionView) {
27///     // Read session state
28///     if let Ok(Some(counter)) = session.get_state("request_count").await {
29///         println!("Session {}: {} requests", session.session_id(), counter);
30///     }
31///
32///     // Write session state
33///     let _ = session.set_state("last_access", json!("2025-10-05")).await;
34/// }
35/// ```
36#[async_trait]
37pub trait SessionView: Send + Sync {
38    /// Get the unique session identifier
39    ///
40    /// # Returns
41    ///
42    /// The session ID as a string reference. Typically a UUID v7 for temporal ordering.
43    fn session_id(&self) -> &str;
44
45    /// Get a state value from the session
46    ///
47    /// # Parameters
48    ///
49    /// - `key`: The state key to retrieve
50    ///
51    /// # Returns
52    ///
53    /// - `Ok(Some(value))`: State value exists
54    /// - `Ok(None)`: State key not found
55    /// - `Err(error)`: Storage error occurred
56    async fn get_state(&self, key: &str) -> Result<Option<Value>, String>;
57
58    /// Set a state value in the session
59    ///
60    /// # Parameters
61    ///
62    /// - `key`: The state key to set
63    /// - `value`: The JSON value to store
64    ///
65    /// # Returns
66    ///
67    /// - `Ok(())`: State was successfully set (or error was logged silently)
68    /// - `Err(error)`: Storage error occurred
69    ///
70    /// **Note**: Current implementation always returns `Ok(())` even if underlying
71    /// storage fails. Errors are logged but not propagated.
72    async fn set_state(&self, key: &str, value: Value) -> Result<(), String>;
73
74    /// Get a metadata value from the session
75    ///
76    /// Metadata is typically set during session initialization and provides
77    /// context about the session (client version, capabilities, etc.).
78    ///
79    /// # Parameters
80    ///
81    /// - `key`: The metadata key to retrieve
82    ///
83    /// # Returns
84    ///
85    /// - `Ok(Some(value))`: Metadata value exists
86    /// - `Ok(None)`: Metadata key not found
87    /// - `Err(error)`: Storage error occurred
88    async fn get_metadata(&self, key: &str) -> Result<Option<Value>, String>;
89
90    /// Set a metadata value in the session
91    ///
92    /// # Parameters
93    ///
94    /// - `key`: The metadata key to set
95    /// - `value`: The JSON value to store
96    ///
97    /// # Returns
98    ///
99    /// - `Ok(())`: Metadata was successfully set (or error was logged silently)
100    /// - `Err(error)`: Storage error occurred
101    ///
102    /// **Note**: Current implementation always returns `Ok(())` even if underlying
103    /// storage fails. Errors are logged but not propagated.
104    async fn set_metadata(&self, key: &str, value: Value) -> Result<(), String>;
105}