From 9287bdf5b77525c920de635df644175b4b0a515b Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Sun, 2 Feb 2020 20:21:07 -0500 Subject: [PATCH] Get rid of mut refs --- youmubot/src/commands/admin/soft_ban.rs | 20 ++++----- youmubot/src/commands/announcer.rs | 15 +++---- youmubot/src/commands/osu/announcer.rs | 7 ++-- youmubot/src/commands/osu/cache.rs | 6 +-- youmubot/src/commands/osu/hook.rs | 5 +-- youmubot/src/commands/osu/mod.rs | 54 +++++++++++-------------- youmubot/src/db/mod.rs | 12 +++--- 7 files changed, 52 insertions(+), 67 deletions(-) diff --git a/youmubot/src/commands/admin/soft_ban.rs b/youmubot/src/commands/admin/soft_ban.rs index 29e7653..0b3aeff 100644 --- a/youmubot/src/commands/admin/soft_ban.rs +++ b/youmubot/src/commands/admin/soft_ban.rs @@ -33,9 +33,9 @@ pub fn soft_ban(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResu }; let guild = msg.guild_id.ok_or(Error::from("Command is guild only"))?; - let mut data = ctx.data.write(); - let mut data = data - .get_mut::() + let data = ctx.data.read(); + let data = data + .get::() .ok_or(Error::from("DB initialized")) .map(|v| DBWriteGuard::from(v))?; let mut data = data.borrow_mut()?; @@ -98,14 +98,14 @@ pub fn soft_ban_init(ctx: &mut Context, msg: &Message, mut args: Args) -> Comman ))); } // Check if we already set up - let mut data = ctx.data.write(); - let mut db: DBWriteGuard<_> = data - .get_mut::() + let data = ctx.data.read(); + let db: DBWriteGuard<_> = data + .get::() .ok_or(Error::from("DB uninitialized"))? .into(); let mut db = db.borrow_mut()?; let server = db - .get_mut(&guild.id) + .get(&guild.id) .map(|v| match v { ServerSoftBans::Unimplemented => false, _ => true, @@ -135,9 +135,9 @@ pub fn watch_soft_bans(client: &mut serenity::Client) -> impl FnOnce() -> () + ' // Scope so that locks are released { // Poll the data for any changes. - let mut data = data.write(); - let mut db: DBWriteGuard<_> = data - .get_mut::() + let data = data.read(); + let db: DBWriteGuard<_> = data + .get::() .expect("DB wrongly initialized") .into(); let mut db = db.borrow_mut().expect("cannot unpack DB"); diff --git a/youmubot/src/commands/announcer.rs b/youmubot/src/commands/announcer.rs index dd25ecd..7a767e5 100644 --- a/youmubot/src/commands/announcer.rs +++ b/youmubot/src/commands/announcer.rs @@ -14,15 +14,12 @@ pub trait Announcer { fn announcer_key() -> &'static str; fn send_messages( c: &Http, - d: &mut ShareMap, + d: &ShareMap, channels: impl Fn(UserId) -> Vec + Sync, ) -> CommandResult; - fn set_channel(d: &mut ShareMap, guild: GuildId, channel: ChannelId) -> CommandResult { - let mut data: DBWriteGuard<_> = d - .get_mut::() - .expect("DB initialized") - .into(); + fn set_channel(d: &ShareMap, guild: GuildId, channel: ChannelId) -> CommandResult { + let data: DBWriteGuard<_> = d.get::().expect("DB initialized").into(); let mut data = data.borrow_mut()?; data.entry(Self::announcer_key().to_owned()) .or_default() @@ -30,7 +27,7 @@ pub trait Announcer { Ok(()) } - fn get_guilds(d: &mut ShareMap) -> Result, Error> { + fn get_guilds(d: &ShareMap) -> Result, Error> { let data = d .get::() .expect("DB initialized") @@ -42,7 +39,7 @@ pub trait Announcer { Ok(data) } - fn announce(c: &Http, d: &mut ShareMap) -> CommandResult { + fn announce(c: &Http, d: &ShareMap) -> CommandResult { let guilds: Vec<_> = Self::get_guilds(d)?; let member_sets = { let mut v = Vec::with_capacity(guilds.len()); @@ -75,7 +72,7 @@ pub trait Announcer { let c = client.cache_and_http.clone(); let data = client.data.clone(); spawn(move || loop { - if let Err(e) = Self::announce(c.http(), &mut *data.write()) { + if let Err(e) = Self::announce(c.http(), &*data.read()) { dbg!(e); } std::thread::sleep(cooldown); diff --git a/youmubot/src/commands/osu/announcer.rs b/youmubot/src/commands/osu/announcer.rs index fa08b3f..d832191 100644 --- a/youmubot/src/commands/osu/announcer.rs +++ b/youmubot/src/commands/osu/announcer.rs @@ -2,10 +2,9 @@ use super::{embeds::score_embed, BeatmapWithMode}; use crate::{ commands::announcer::Announcer, db::{OsuSavedUsers, OsuUser}, - http::{Osu, HTTP}, + http::Osu, }; use rayon::prelude::*; -use reqwest::blocking::Client as HTTPClient; use serenity::{ framework::standard::{CommandError as Error, CommandResult}, http::Http, @@ -30,7 +29,7 @@ impl Announcer for OsuAnnouncer { } fn send_messages( c: &Http, - d: &mut ShareMap, + d: &ShareMap, channels: impl Fn(UserId) -> Vec + Sync, ) -> CommandResult { let osu = d.get::().expect("osu!client").clone(); @@ -87,7 +86,7 @@ impl Announcer for OsuAnnouncer { osu_user.last_update = chrono::Utc::now(); } // Update users - let f = d.get_mut::().expect("DB initialized"); + let f = d.get::().expect("DB initialized"); f.write(|f| *f = data)?; f.save()?; Ok(()) diff --git a/youmubot/src/commands/osu/cache.rs b/youmubot/src/commands/osu/cache.rs index 0709d34..e52355b 100644 --- a/youmubot/src/commands/osu/cache.rs +++ b/youmubot/src/commands/osu/cache.rs @@ -8,12 +8,12 @@ use serenity::{ /// Save the beatmap into the server data storage. pub(crate) fn save_beatmap( - data: &mut ShareMap, + data: &ShareMap, channel_id: ChannelId, bm: &BeatmapWithMode, ) -> CommandResult { - let mut db: DBWriteGuard<_> = data - .get_mut::() + let db: DBWriteGuard<_> = data + .get::() .expect("DB is implemented") .into(); let mut db = db.borrow_mut()?; diff --git a/youmubot/src/commands/osu/hook.rs b/youmubot/src/commands/osu/hook.rs index 3c1adbc..c087580 100644 --- a/youmubot/src/commands/osu/hook.rs +++ b/youmubot/src/commands/osu/hook.rs @@ -47,7 +47,7 @@ pub fn hook(ctx: &mut Context, msg: &Message) -> () { } // Save the beatmap for query later. if let Some(t) = last_beatmap { - if let Err(v) = super::cache::save_beatmap(&mut *ctx.data.write(), msg.channel_id, &t) { + if let Err(v) = super::cache::save_beatmap(&*ctx.data.read(), msg.channel_id, &t) { dbg!(v); } } @@ -121,8 +121,7 @@ fn handle_old_links<'a>(ctx: &mut Context, content: &'a str) -> Result(ctx: &mut Context, content: &'a str) -> Result>, Error> { - let data = ctx.data.write(); - let osu = data.get::().unwrap().clone(); + let osu = ctx.data.read().get::().unwrap().clone(); let mut to_prints: Vec> = Vec::new(); for capture in NEW_LINK_REGEX.captures_iter(content) { let mode = capture.name("mode").and_then(|v| { diff --git a/youmubot/src/commands/osu/mod.rs b/youmubot/src/commands/osu/mod.rs index 2e8fac2..571c6d6 100644 --- a/youmubot/src/commands/osu/mod.rs +++ b/youmubot/src/commands/osu/mod.rs @@ -97,9 +97,9 @@ pub fn save(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { let user: Option = osu.user(UserID::Auto(user), |f| f)?; match user { Some(u) => { - let mut db = ctx.data.write(); - let mut db: DBWriteGuard<_> = db - .get_mut::() + let db = ctx.data.read(); + let db: DBWriteGuard<_> = db + .get::() .ok_or(Error::from("DB uninitialized"))? .into(); let mut db = db.borrow_mut()?; @@ -147,18 +147,14 @@ enum UsernameArg { } impl UsernameArg { - fn to_user_id_query( - s: Option, - data: &mut ShareMap, - msg: &Message, - ) -> Result { + fn to_user_id_query(s: Option, data: &ShareMap, msg: &Message) -> Result { let id = match s { Some(UsernameArg::Raw(s)) => return Ok(UserID::Auto(s)), Some(UsernameArg::Tagged(r)) => r, None => msg.author.id, }; let db: DBWriteGuard<_> = data - .get_mut::() + .get::() .ok_or(Error::from("DB uninitialized"))? .into(); let db = db.borrow()?; @@ -202,11 +198,8 @@ impl FromStr for Nth { pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { let nth = args.single::().unwrap_or(Nth(1)).0.min(50).max(1); let mode = args.single::().unwrap_or(ModeArg(Mode::Std)).0; - let user = UsernameArg::to_user_id_query( - args.single::().ok(), - &mut *ctx.data.write(), - msg, - )?; + let user = + UsernameArg::to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; let osu: OsuClient = ctx.data.read().get::().unwrap().clone(); let user = osu @@ -235,7 +228,7 @@ pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult })?; // Save the beatmap... - cache::save_beatmap(&mut *ctx.data.write(), msg.channel_id, &beatmap)?; + cache::save_beatmap(&*ctx.data.read(), msg.channel_id, &beatmap)?; Ok(()) } @@ -244,9 +237,7 @@ pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult #[description = "Show information from the last queried beatmap."] #[num_args(0)] pub fn last(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult { - let mut data = ctx.data.write(); - - let b = cache::get_beatmap(&mut *data, msg.channel_id)?; + let b = cache::get_beatmap(&*ctx.data.read(), msg.channel_id)?; match b { Some(BeatmapWithMode(b, m)) => { @@ -271,9 +262,7 @@ pub fn last(ctx: &mut Context, msg: &Message, _: Args) -> CommandResult { #[description = "Check your own or someone else's best record on the last beatmap."] #[max_args(1)] pub fn check(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { - let mut data = ctx.data.write(); - - let bm = cache::get_beatmap(&mut *data, msg.channel_id)?; + let bm = cache::get_beatmap(&*ctx.data.read(), msg.channel_id)?; match bm { None => { @@ -282,10 +271,13 @@ pub fn check(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult Some(bm) => { let b = &bm.0; let m = bm.1; - let user = - UsernameArg::to_user_id_query(args.single::().ok(), &mut *data, msg)?; + let user = UsernameArg::to_user_id_query( + args.single::().ok(), + &*ctx.data.read(), + msg, + )?; - let osu = data.get::().unwrap().clone(); + let osu = ctx.data.read().get::().unwrap().clone(); let user = osu .user(user, |f| f)? @@ -319,10 +311,10 @@ pub fn top(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { .map(|ModeArg(t)| t) .unwrap_or(Mode::Std); - let mut data = ctx.data.write(); - let user = UsernameArg::to_user_id_query(args.single::().ok(), &mut *data, msg)?; + let user = + UsernameArg::to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; - let osu: OsuClient = data.get::().unwrap().clone(); + let osu: OsuClient = ctx.data.read().get::().unwrap().clone(); let user = osu .user(user, |f| f.mode(mode))? .ok_or(Error::from("User not found"))?; @@ -352,15 +344,15 @@ pub fn top(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { })?; // Save the beatmap... - cache::save_beatmap(&mut *data, msg.channel_id, &beatmap)?; + cache::save_beatmap(&*ctx.data.read(), msg.channel_id, &beatmap)?; Ok(()) } fn get_user(ctx: &mut Context, msg: &Message, mut args: Args, mode: Mode) -> CommandResult { - let mut data = ctx.data.write(); - let user = UsernameArg::to_user_id_query(args.single::().ok(), &mut *data, msg)?; - let osu = data.get::().unwrap().clone(); + let user = + UsernameArg::to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; + let osu = ctx.data.read().get::().unwrap().clone(); let user = osu.user(user, |f| f.mode(mode))?; match user { Some(u) => { diff --git a/youmubot/src/db/mod.rs b/youmubot/src/db/mod.rs index e15517e..e8f4c98 100644 --- a/youmubot/src/db/mod.rs +++ b/youmubot/src/db/mod.rs @@ -63,15 +63,15 @@ pub fn setup_db(client: &mut Client) -> Result<(), Error> { Ok(()) } -pub struct DBWriteGuard<'a, T>(&'a mut FileDatabase) +pub struct DBWriteGuard<'a, T>(&'a FileDatabase) where T: Send + Sync + Clone + std::fmt::Debug + Serialize + DeserializeOwned; -impl<'a, T> From<&'a mut FileDatabase> for DBWriteGuard<'a, T> +impl<'a, T> From<&'a FileDatabase> for DBWriteGuard<'a, T> where T: Send + Sync + Clone + std::fmt::Debug + Serialize + DeserializeOwned, { - fn from(v: &'a mut FileDatabase) -> Self { + fn from(v: &'a FileDatabase) -> Self { DBWriteGuard(v) } } @@ -83,9 +83,7 @@ where pub fn borrow(&self) -> Result, rustbreak::RustbreakError> { (*self).0.borrow_data() } - pub fn borrow_mut( - &mut self, - ) -> Result, rustbreak::RustbreakError> { + pub fn borrow_mut(&self) -> Result, rustbreak::RustbreakError> { (*self).0.borrow_data_mut() } } @@ -112,7 +110,7 @@ impl ServerSoftBans { // Create a new, implemented role. pub fn new_implemented(role: RoleId) -> ServerSoftBans { ServerSoftBans::Implemented(ImplementedSoftBans { - role: role, + role, periodical_bans: HashMap::new(), }) }