turul_mcp_session_storage/
lib.rs1mod traits;
25pub use traits::*;
27
28mod session_view;
29pub use session_view::SessionView;
30
31pub mod in_memory;
33pub mod prelude;
34
35#[cfg(feature = "sqlite")]
36pub mod sqlite;
37
38#[cfg(feature = "postgres")]
39pub mod postgres;
40
41#[cfg(feature = "dynamodb")]
42pub mod dynamodb;
43
44pub use in_memory::{InMemoryConfig, InMemoryError, InMemorySessionStorage, InMemoryStats};
47
48#[cfg(feature = "sqlite")]
49pub use sqlite::{SqliteConfig, SqliteError, SqliteSessionStorage};
51
52#[cfg(feature = "postgres")]
53pub use postgres::{PostgresConfig, PostgresError, PostgresSessionStorage};
55
56#[cfg(feature = "dynamodb")]
57pub use dynamodb::{DynamoDbConfig, DynamoDbError, DynamoDbSessionStorage};
59
60pub type StorageResult<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
62
63pub fn create_default_storage() -> InMemorySessionStorage {
65 InMemorySessionStorage::new()
66}
67
68pub fn create_memory_storage(config: InMemoryConfig) -> InMemorySessionStorage {
70 InMemorySessionStorage::with_config(config)
71}
72
73#[cfg(feature = "sqlite")]
75pub async fn create_sqlite_storage() -> Result<SqliteSessionStorage, SqliteError> {
76 SqliteSessionStorage::new().await
77}
78
79#[cfg(feature = "sqlite")]
81pub async fn create_sqlite_storage_with_config(
82 config: SqliteConfig,
83) -> Result<SqliteSessionStorage, SqliteError> {
84 SqliteSessionStorage::with_config(config).await
85}
86
87#[cfg(feature = "postgres")]
89pub async fn create_postgres_storage() -> Result<PostgresSessionStorage, PostgresError> {
90 PostgresSessionStorage::new().await
91}
92
93#[cfg(feature = "postgres")]
95pub async fn create_postgres_storage_with_config(
96 config: PostgresConfig,
97) -> Result<PostgresSessionStorage, PostgresError> {
98 PostgresSessionStorage::with_config(config).await
99}
100
101#[cfg(feature = "dynamodb")]
103pub async fn create_dynamodb_storage() -> Result<DynamoDbSessionStorage, DynamoDbError> {
104 DynamoDbSessionStorage::new().await
105}
106
107#[cfg(feature = "dynamodb")]
109pub async fn create_dynamodb_storage_with_config(
110 config: DynamoDbConfig,
111) -> Result<DynamoDbSessionStorage, DynamoDbError> {
112 DynamoDbSessionStorage::with_config(config).await
113}
114
115#[cfg(test)]
116mod integration_tests {
117 use super::*;
118 use turul_mcp_protocol::ServerCapabilities;
119
120 #[tokio::test]
121 async fn test_storage_trait_compliance() {
122 let storage = create_default_storage();
123
124 let session = storage
126 .create_session(ServerCapabilities::default())
127 .await
128 .unwrap();
129 let session_id = session.session_id.clone();
130
131 assert!(storage.get_session(&session_id).await.unwrap().is_some());
133 assert_eq!(storage.session_count().await.unwrap(), 1);
134
135 storage
137 .set_session_state(&session_id, "test", serde_json::json!("value"))
138 .await
139 .unwrap();
140 let value = storage
141 .get_session_state(&session_id, "test")
142 .await
143 .unwrap();
144 assert_eq!(value, Some(serde_json::json!("value")));
145
146 let event = crate::SseEvent::new("test".to_string(), serde_json::json!({"data": "test"}));
148 let stored = storage.store_event(&session_id, event).await.unwrap();
149 assert!(stored.id > 0);
150
151 let deleted = storage.delete_session(&session_id).await.unwrap();
153 assert!(deleted);
154 assert_eq!(storage.session_count().await.unwrap(), 0);
155 }
156}