pub mod channel_data; pub mod guild_data; pub mod reminder; pub mod timer; pub mod user_data; use std::sync::Arc; use guild_data::GuildData; use serenity::{ async_trait, model::id::{GuildId, UserId}, prelude::Context, }; use tokio::sync::RwLock; use crate::{consts::DEFAULT_PREFIX, models::user_data::UserData, GuildDataCache, SQLPool}; #[async_trait] pub trait CtxData { async fn guild_data + Send + Sync>( &self, guild_id: G, ) -> Result>, sqlx::Error>; async fn user_data + Send + Sync>( &self, user_id: U, ) -> Result>; async fn prefix + Send + Sync>(&self, guild_id: Option) -> String; } #[async_trait] impl CtxData for Context { async fn guild_data + Send + Sync>( &self, guild_id: G, ) -> Result>, sqlx::Error> { let guild_id = guild_id.into(); let guild = guild_id.to_guild_cached(&self.cache).unwrap(); let guild_cache = self .data .read() .await .get::() .cloned() .unwrap(); let x = if let Some(guild_data) = guild_cache.get(&guild_id) { Ok(guild_data.clone()) } else { let pool = self.data.read().await.get::().cloned().unwrap(); match GuildData::from_guild(guild, &pool).await { Ok(d) => { let lock = Arc::new(RwLock::new(d)); guild_cache.insert(guild_id, lock.clone()); Ok(lock) } Err(e) => Err(e), } }; x } async fn user_data + Send + Sync>( &self, user_id: U, ) -> Result> { let user_id = user_id.into(); let pool = self.data.read().await.get::().cloned().unwrap(); let user = user_id.to_user(self).await.unwrap(); UserData::from_user(&user, &self, &pool).await } async fn prefix + Send + Sync>(&self, guild_id: Option) -> String { if let Some(guild_id) = guild_id { self.guild_data(guild_id) .await .unwrap() .read() .await .prefix .clone() } else { DEFAULT_PREFIX.clone() } } }