use dashmap::DashMap;
use std::any::{Any, TypeId};
use std::sync::Arc;
#[derive(Clone, Default)]
pub struct StateStorage {
inner: Arc<DashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
}
impl StateStorage {
pub fn new() -> Self {
Self::default()
}
pub fn insert<T: Any + Send + Sync + 'static>(&self, value: T) {
self.inner.insert(TypeId::of::<T>(), Arc::new(value));
}
pub fn get<T: Any + Send + Sync + Clone + 'static>(&self) -> Option<T> {
self.inner
.get(&TypeId::of::<T>())
.and_then(|v| v.downcast_ref::<T>().cloned())
}
pub fn get_arc<T: Any + Send + Sync + 'static>(&self) -> Option<Arc<T>> {
self.inner
.get(&TypeId::of::<T>())
.and_then(|v| Arc::clone(&*v).downcast::<T>().ok())
}
}
#[derive(Clone, Default)]
pub struct DialogueStorage {
inner: Arc<DashMap<(i64, i64), Arc<dyn Any + Send + Sync>>>,
}
impl DialogueStorage {
pub fn new() -> Self {
Self::default()
}
pub fn set<S: Any + Send + Sync + 'static>(&self, chat_id: i64, user_id: i64, state: S) {
self.inner.insert((chat_id, user_id), Arc::new(state));
}
pub fn get<S: Any + Send + Sync + Clone + 'static>(
&self,
chat_id: i64,
user_id: i64,
) -> Option<S> {
self.inner
.get(&(chat_id, user_id))
.and_then(|v| v.downcast_ref::<S>().cloned())
}
pub fn remove(&self, chat_id: i64, user_id: i64) {
self.inner.remove(&(chat_id, user_id));
}
}