use {async_trait::async_trait, std::collections::HashMap, tokio::sync::RwLock};
use crate::{
models::{events::ServerEvent, Channel, Id, Member, MemberId, Server, User},
Context,
};
#[derive(Debug, Default)]
pub struct Cache {
pub(crate) users: RwLock<HashMap<Id, User>>,
pub(crate) channels: RwLock<HashMap<Id, Channel>>,
pub(crate) servers: RwLock<HashMap<Id, Server>>,
pub(crate) members: RwLock<HashMap<MemberId, Member>>,
}
impl Cache {
pub(crate) async fn update(cx: &Context, event: &ServerEvent) {
match event {
ServerEvent::Ready(event) => event.update(cx).await,
ServerEvent::Message(event) => event.update(cx).await,
ServerEvent::ChannelCreate(event) => event.update(cx).await,
ServerEvent::ChannelUpdate(event) => event.update(cx).await,
ServerEvent::ChannelDelete(event) => event.update(cx).await,
ServerEvent::ChannelGroupJoin(event) => event.update(cx).await,
ServerEvent::ChannelGroupLeave(event) => event.update(cx).await,
ServerEvent::ServerUpdate(event) => event.update(cx).await,
ServerEvent::ServerDelete(event) => event.update(cx).await,
ServerEvent::ServerMemberUpdate(event) => event.update(cx).await,
ServerEvent::ServerMemberJoin(event) => event.update(cx).await,
ServerEvent::ServerMemberLeave(event) => event.update(cx).await,
ServerEvent::UserUpdate(event) => event.update(cx).await,
_ => return,
}
}
pub async fn user(&self, id: &Id) -> Option<User> {
self.users.read().await.get(id).cloned()
}
pub async fn users(&self) -> HashMap<Id, User> {
self.users.read().await.clone()
}
pub async fn filter_users(&self, filter: impl Fn(&User) -> bool) -> Vec<User> {
self.users
.read()
.await
.iter()
.filter_map(|(_, user)| {
if filter(user) {
return Some(user);
}
None
})
.cloned()
.collect()
}
pub async fn channel(&self, id: &Id) -> Option<Channel> {
self.channels.read().await.get(id).cloned()
}
pub async fn channels(&self) -> HashMap<Id, Channel> {
self.channels.read().await.clone()
}
pub async fn filter_channels(&self, filter: impl Fn(&Channel) -> bool) -> Vec<Channel> {
self.channels
.read()
.await
.iter()
.filter_map(|(_, channel)| {
if filter(channel) {
return Some(channel);
}
None
})
.cloned()
.collect()
}
pub async fn server(&self, id: &Id) -> Option<Server> {
self.servers.read().await.get(id).cloned()
}
pub async fn servers(&self) -> HashMap<Id, Server> {
self.servers.read().await.clone()
}
pub async fn filter_servers(&self, filter: impl Fn(&Server) -> bool) -> Vec<Server> {
self.servers
.read()
.await
.iter()
.filter_map(|(_, server)| {
if filter(server) {
return Some(server);
}
None
})
.cloned()
.collect()
}
pub async fn servers_count(&self) -> usize {
self.servers.read().await.len()
}
pub async fn member(&self, id: &MemberId) -> Option<Member> {
self.members.read().await.get(id).cloned()
}
pub async fn members(&self) -> HashMap<MemberId, Member> {
self.members.read().await.clone()
}
pub async fn filter_members(&self, filter: impl Fn(&Member) -> bool) -> Vec<Member> {
self.members
.read()
.await
.iter()
.filter_map(|(_, member)| {
if filter(member) {
return Some(member);
}
None
})
.cloned()
.collect()
}
}
#[async_trait]
pub(crate) trait UpdateCache {
async fn update(&self, cx: &Context);
}