pub mod channel_data; pub mod command_macro; pub mod guild_data; pub mod reminder; pub mod timer; pub mod user_data; use chrono_tz::Tz; use poise::serenity_prelude::{async_trait, model::id::UserId}; use crate::{ models::{channel_data::ChannelData, guild_data::GuildData, user_data::UserData}, CommandMacro, Context, Data, Error, GuildId, }; #[async_trait] pub trait CtxData { async fn user_data + Send>(&self, user_id: U) -> Result; async fn author_data(&self) -> Result; async fn guild_data(&self) -> Option>; async fn timezone(&self) -> Tz; async fn channel_data(&self) -> Result; async fn command_macros(&self) -> Result, Error>; } #[async_trait] impl CtxData for Context<'_> { async fn user_data + Send>(&self, user_id: U) -> Result { UserData::from_user(user_id, &self.serenity_context(), &self.data().database).await } async fn author_data(&self) -> Result { UserData::from_user(&self.author().id, &self.serenity_context(), &self.data().database) .await } async fn guild_data(&self) -> Option> { if let Some(guild_id) = self.guild_id() { Some(GuildData::from_guild(guild_id, &self.data().database).await) } else { None } } async fn timezone(&self) -> Tz { UserData::timezone_of(self.author().id, &self.data().database).await } async fn channel_data(&self) -> Result> { // If we're in a thread, get the parent channel. let channel = self.channel_id().to_channel(&self).await?; ChannelData::from_channel(&channel, &self.data().database).await } async fn command_macros(&self) -> Result, Error> { self.data().command_macros(self.guild_id().unwrap()).await } } impl Data { pub(crate) async fn command_macros( &self, guild_id: GuildId, ) -> Result, Error> { let rows = sqlx::query!( "SELECT name, description, commands FROM macro WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)", guild_id.get() ) .fetch_all(&self.database) .await?.iter().map(|row| CommandMacro { guild_id, name: row.name.clone(), description: row.description.clone(), commands: serde_json::from_str(&row.commands).unwrap(), }).collect(); Ok(rows) } }