From 2820b025b84a86cf362ca110be8fa31e6187a026 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Fri, 17 Jan 2020 03:49:55 -0500 Subject: [PATCH] Implement a better Announcer trait --- youmubot/src/commands/announcer.rs | 55 +++++++++++++++++++++++------- youmubot/src/commands/osu/mod.rs | 1 + 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/youmubot/src/commands/announcer.rs b/youmubot/src/commands/announcer.rs index 4e98114..73557b0 100644 --- a/youmubot/src/commands/announcer.rs +++ b/youmubot/src/commands/announcer.rs @@ -1,8 +1,9 @@ +use crate::db::{AnnouncerChannels, DBWriteGuard}; use serenity::{ - builder::CreateMessage, framework::standard::{CommandError as Error, CommandResult}, http::{CacheHttp, Http}, model::id::{ChannelId, GuildId, UserId}, + prelude::ShareMap, }; use std::{ collections::HashSet, @@ -10,13 +11,39 @@ use std::{ }; pub trait Announcer { - type MessageSender: for<'a, 'r> Fn(&'r mut CreateMessage<'a>) -> &'r mut CreateMessage<'a>; + fn announcer_key() -> &'static str; + fn send_messages( + c: &Http, + d: &mut ShareMap, + channels: impl Fn(UserId) -> Vec, + ) -> CommandResult; - fn get_guilds(c: impl AsRef) -> Result, Error>; - fn fetch_messages(c: impl AsRef) -> Result, Error>; + fn set_channel(d: &mut ShareMap, guild: GuildId, channel: ChannelId) -> CommandResult { + let mut data: DBWriteGuard<_> = d + .get_mut::() + .expect("DB initialized") + .into(); + let mut data = data.borrow_mut()?; + data.entry(Self::announcer_key().to_owned()) + .or_default() + .insert(guild, channel); + Ok(()) + } - fn announce(c: impl AsRef) -> CommandResult { - let guilds: Vec<_> = Self::get_guilds(c.as_ref())?; + fn get_guilds(d: &mut ShareMap) -> Result, Error> { + let data = d + .get::() + .expect("DB initialized") + .read(|v| { + v.get(Self::announcer_key()) + .map(|m| m.iter().map(|(a, b)| (*a, *b)).collect()) + .unwrap_or_else(|| vec![]) + })?; + Ok(data) + } + + fn announce(c: &Http, d: &mut ShareMap) -> CommandResult { + let guilds: Vec<_> = Self::get_guilds(d)?; let member_sets = { let mut v = Vec::with_capacity(guilds.len()); for (guild, channel) in guilds.into_iter() { @@ -28,21 +55,23 @@ pub trait Announcer { } v }; - for (user_id, f) in Self::fetch_messages(c.as_ref())?.into_iter() { + Self::send_messages(c.as_ref(), d, |user_id| { + let mut v = Vec::new(); for (members, channel) in member_sets.iter() { if members.contains(&user_id) { - if let Err(e) = channel.send_message(c.as_ref(), &f) { - dbg!((user_id, channel, e)); - } + v.push(*channel); } } - } + v + })?; Ok(()) } - fn scan(c: impl CacheHttp + 'static + Send, cooldown: std::time::Duration) -> JoinHandle<()> { + fn scan(client: &serenity::Client, cooldown: std::time::Duration) -> JoinHandle<()> { + let c = client.cache_and_http.clone(); + let data = client.data.clone(); spawn(move || loop { - if let Err(e) = Self::announce(c.http()) { + if let Err(e) = Self::announce(c.http(), &mut *data.write()) { dbg!(e); } std::thread::sleep(cooldown); diff --git a/youmubot/src/commands/osu/mod.rs b/youmubot/src/commands/osu/mod.rs index 4217d7d..c0e67ce 100644 --- a/youmubot/src/commands/osu/mod.rs +++ b/youmubot/src/commands/osu/mod.rs @@ -16,6 +16,7 @@ use youmubot_osu::{ Client as OsuClient, }; +mod announcer; mod cache; pub(crate) mod embeds; mod hook;