diff --git a/CHANGELOG.md b/CHANGELOG.md index 48f67379..0b3cc0a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## unreleased +### Added + +- The `Storage::erase` default function that returns `ErasedStorage`. +- `ErasedStorage`, a storage with an erased error type. + ## 0.7.1 - 2022-03-09 ### Fixed diff --git a/src/dispatching/dialogue/mod.rs b/src/dispatching/dialogue/mod.rs index 3f336d73..8c6e6bae 100644 --- a/src/dispatching/dialogue/mod.rs +++ b/src/dispatching/dialogue/mod.rs @@ -169,4 +169,4 @@ pub use storage::{RedisStorage, RedisStorageError}; #[cfg(feature = "sqlite-storage")] pub use storage::{SqliteStorage, SqliteStorageError}; -pub use storage::{serializer, InMemStorage, InMemStorageError, Serializer, Storage, TraceStorage}; +pub use storage::*; diff --git a/src/dispatching/dialogue/storage/mod.rs b/src/dispatching/dialogue/storage/mod.rs index 506e18bf..93dec439 100644 --- a/src/dispatching/dialogue/storage/mod.rs +++ b/src/dispatching/dialogue/storage/mod.rs @@ -72,4 +72,79 @@ pub trait Storage { self: Arc, chat_id: i64, ) -> BoxFuture<'static, Result, Self::Error>>; + + /// Erases [`Self::Error`] to [`std::error::Error`]. + fn erase(self: Arc) -> ErasedStorage + where + Self: Sized + Send + Sync + 'static, + Self::Error: std::error::Error + 'static, + { + struct Eraser(Arc); + + impl Storage for Eraser + where + S: Storage + Send + Sync + 'static, + S::Error: std::error::Error + 'static, + { + type Error = Box; + + fn remove_dialogue( + self: Arc, + chat_id: i64, + ) -> BoxFuture<'static, Result<(), Self::Error>> + where + D: Send + 'static, + { + Box::pin(async move { + Arc::clone(&self.0).remove_dialogue(chat_id).await.map_err(|e| e.into()) + }) + } + + fn update_dialogue( + self: Arc, + chat_id: i64, + dialogue: D, + ) -> BoxFuture<'static, Result<(), Self::Error>> + where + D: Send + 'static, + { + Box::pin(async move { + Arc::clone(&self.0) + .update_dialogue(chat_id, dialogue) + .await + .map_err(|e| e.into()) + }) + } + + fn get_dialogue( + self: Arc, + chat_id: i64, + ) -> BoxFuture<'static, Result, Self::Error>> { + Box::pin(async move { + Arc::clone(&self.0).get_dialogue(chat_id).await.map_err(|e| e.into()) + }) + } + } + + Arc::new(Eraser(self)) + } +} + +/// A storage with an erased error type. +pub type ErasedStorage = Arc>>; + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_erased() { + let chat_id = 123; + + let erased = InMemStorage::new().erase(); + Arc::clone(&erased).update_dialogue(chat_id, 1).await.unwrap(); + assert_eq!(Arc::clone(&erased).get_dialogue(chat_id).await.unwrap().unwrap(), 1); + Arc::clone(&erased).remove_dialogue(chat_id).await.unwrap(); + assert_eq!(Arc::clone(&erased).get_dialogue(chat_id).await.unwrap(), None); + } } diff --git a/src/dispatching2/dialogue/mod.rs b/src/dispatching2/dialogue/mod.rs index cf9867ed..1dbdc279 100644 --- a/src/dispatching2/dialogue/mod.rs +++ b/src/dispatching2/dialogue/mod.rs @@ -92,7 +92,7 @@ pub use crate::dispatching::dialogue::{RedisStorage, RedisStorageError}; pub use crate::dispatching::dialogue::{SqliteStorage, SqliteStorageError}; pub use crate::dispatching::dialogue::{ - serializer, InMemStorage, InMemStorageError, Serializer, Storage, TraceStorage, + serializer, ErasedStorage, InMemStorage, InMemStorageError, Serializer, Storage, TraceStorage, }; pub use get_chat_id::GetChatId; diff --git a/src/utils/command.rs b/src/utils/command.rs index 41e394f1..cef3e533 100644 --- a/src/utils/command.rs +++ b/src/utils/command.rs @@ -337,7 +337,7 @@ where let command = splited.next()?; let bot = splited.next(); match bot { - Some(name) if name == bot_name.as_ref() => {} + Some(name) if name.eq_ignore_ascii_case(bot_name.as_ref()) => {} None => {} _ => return None, }