Massive lint fix

This commit is contained in:
Natsu Kagami 2023-10-22 17:45:13 +02:00
parent 1a6039aa94
commit 54502ad61b
Signed by: nki
GPG key ID: 55A032EB38B49ADB
28 changed files with 117 additions and 122 deletions

View file

@ -24,14 +24,14 @@ impl youmubot_prelude::Announcer for Announcer {
) -> Result<()> { ) -> Result<()> {
let data = data.read().await; let data = data.read().await;
let client = data.get::<CFClient>().unwrap(); let client = data.get::<CFClient>().unwrap();
let mut users = CfSavedUsers::open(&*data).borrow()?.clone(); let mut users = CfSavedUsers::open(&data).borrow()?.clone();
users users
.iter_mut() .iter_mut()
.map(|(user_id, cfu)| { .map(|(user_id, cfu)| {
let http = http.clone(); let http = http.clone();
let channels = &channels; let channels = &channels;
async move { async move {
if let Err(e) = update_user(http, &channels, &client, *user_id, cfu).await { if let Err(e) = update_user(http, channels, client, *user_id, cfu).await {
cfu.failures += 1; cfu.failures += 1;
eprintln!( eprintln!(
"Codeforces: cannot update user {}: {} [{} failures]", "Codeforces: cannot update user {}: {} [{} failures]",
@ -45,7 +45,7 @@ impl youmubot_prelude::Announcer for Announcer {
.collect::<stream::FuturesUnordered<_>>() .collect::<stream::FuturesUnordered<_>>()
.collect::<()>() .collect::<()>()
.await; .await;
let mut db = CfSavedUsers::open(&*data); let mut db = CfSavedUsers::open(&data);
let mut db = db.borrow_mut()?; let mut db = db.borrow_mut()?;
for (key, user) in users { for (key, user) in users {
match db.get(&key).map(|v| v.last_update) { match db.get(&key).map(|v| v.last_update) {
@ -74,13 +74,13 @@ async fn update_user(
user_id: UserId, user_id: UserId,
cfu: &mut CfUser, cfu: &mut CfUser,
) -> Result<()> { ) -> Result<()> {
let info = User::info(&*client, &[cfu.handle.as_str()]) let info = User::info(client, &[cfu.handle.as_str()])
.await? .await?
.into_iter() .into_iter()
.next() .next()
.ok_or_else(|| Error::msg("Not found"))?; .ok_or_else(|| Error::msg("Not found"))?;
let rating_changes = info.rating_changes(&*client).await?; let rating_changes = info.rating_changes(client).await?;
let channels_list = channels.channels_of(&http, user_id).await; let channels_list = channels.channels_of(&http, user_id).await;
cfu.last_update = Utc::now(); cfu.last_update = Utc::now();
@ -119,7 +119,7 @@ async fn update_user(
return Ok(()); return Ok(());
} }
let (contest, _, _) = let (contest, _, _) =
codeforces::Contest::standings(&*client, rc.contest_id, |f| f.limit(1, 1)) codeforces::Contest::standings(client, rc.contest_id, |f| f.limit(1, 1))
.await?; .await?;
channels channels
.iter() .iter()

View file

@ -26,7 +26,7 @@ pub fn user_embed<'a>(user: &User, e: &'a mut CreateEmbed) -> &'a mut CreateEmbe
.join(", "); .join(", ");
e.color(user.color()) e.color(user.color())
.author(|a| a.name(&rank)) .author(|a| a.name(&rank))
.thumbnail(format!("{}", user.title_photo)) .thumbnail(user.title_photo.to_string())
.title(&user.handle) .title(&user.handle)
.url(user.profile_url()) .url(user.profile_url())
.description(format!( .description(format!(
@ -63,7 +63,7 @@ pub fn rating_change_embed<'a>(
user_id: serenity::model::id::UserId, user_id: serenity::model::id::UserId,
e: &'a mut CreateEmbed, e: &'a mut CreateEmbed,
) -> &'a mut CreateEmbed { ) -> &'a mut CreateEmbed {
let delta = (rating_change.new_rating as i64) - (rating_change.old_rating as i64); let delta = rating_change.new_rating - rating_change.old_rating;
let color = if delta < 0 { 0xff0000 } else { 0x00ff00 }; let color = if delta < 0 { 0xff0000 } else { 0x00ff00 };
let message = if delta > 0 { let message = if delta > 0 {
MessageBuilder::new() MessageBuilder::new()
@ -90,7 +90,7 @@ pub fn rating_change_embed<'a>(
}; };
e.author(|a| { e.author(|a| {
a.icon_url(format!("{}", &user.avatar)) a.icon_url(user.avatar.to_string())
.url(user.profile_url()) .url(user.profile_url())
.name(&user.handle) .name(&user.handle)
}) })

View file

@ -53,8 +53,8 @@ impl ContestCache {
async fn fetch_contest_list(http: Client) -> Result<StdHashMap<u64, Contest>> { async fn fetch_contest_list(http: Client) -> Result<StdHashMap<u64, Contest>> {
log::info!("Fetching contest list, this might take a few seconds to complete..."); log::info!("Fetching contest list, this might take a few seconds to complete...");
let gyms = Contest::list(&*http, true).await?; let gyms = Contest::list(&http, true).await?;
let contests = Contest::list(&*http, false).await?; let contests = Contest::list(&http, false).await?;
let r: StdHashMap<u64, Contest> = gyms let r: StdHashMap<u64, Contest> = gyms
.into_iter() .into_iter()
.chain(contests.into_iter()) .chain(contests.into_iter())
@ -78,7 +78,7 @@ impl ContestCache {
&self, &self,
contest_id: u64, contest_id: u64,
) -> Result<(Contest, Option<Vec<Problem>>)> { ) -> Result<(Contest, Option<Vec<Problem>>)> {
let (c, p) = match Contest::standings(&*self.http, contest_id, |f| f.limit(1, 1)).await { let (c, p) = match Contest::standings(&self.http, contest_id, |f| f.limit(1, 1)).await {
Ok((c, p, _)) => (c, Some(p)), Ok((c, p, _)) => (c, Some(p)),
Err(codeforces::Error::Codeforces(s)) if s.ends_with("has not started") => { Err(codeforces::Error::Codeforces(s)) if s.ends_with("has not started") => {
let c = self.get_from_list(contest_id).await?; let c = self.get_from_list(contest_id).await?;

View file

@ -63,7 +63,7 @@ pub async fn profile(ctx: &Context, m: &Message, mut args: Args) -> CommandResul
let handle = match handle { let handle = match handle {
UsernameArg::Raw(s) => s, UsernameArg::Raw(s) => s,
UsernameArg::Tagged(u) => { UsernameArg::Tagged(u) => {
let db = CfSavedUsers::open(&*data); let db = CfSavedUsers::open(&data);
let user = db.borrow()?.get(&u).map(|u| u.handle.clone()); let user = db.borrow()?.get(&u).map(|u| u.handle.clone());
match user { match user {
Some(v) => v, Some(v) => v,
@ -75,7 +75,7 @@ pub async fn profile(ctx: &Context, m: &Message, mut args: Args) -> CommandResul
} }
}; };
let account = codeforces::User::info(&*http, &[&handle[..]]) let account = codeforces::User::info(http, &[&handle[..]])
.await? .await?
.into_iter() .into_iter()
.next(); .next();
@ -107,7 +107,7 @@ pub async fn save(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
let handle = args.single::<String>()?; let handle = args.single::<String>()?;
let http = data.get::<CFClient>().unwrap(); let http = data.get::<CFClient>().unwrap();
let account = codeforces::User::info(&*http, &[&handle[..]]) let account = codeforces::User::info(http, &[&handle[..]])
.await? .await?
.into_iter() .into_iter()
.next(); .next();
@ -119,8 +119,8 @@ pub async fn save(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
} }
Some(acc) => { Some(acc) => {
// Collect rating changes data. // Collect rating changes data.
let rating_changes = acc.rating_changes(&*http).await?; let rating_changes = acc.rating_changes(http).await?;
let mut db = CfSavedUsers::open(&*data); let mut db = CfSavedUsers::open(&data);
m.reply( m.reply(
&ctx, &ctx,
format!("account `{}` has been linked to your account.", &acc.handle), format!("account `{}` has been linked to your account.", &acc.handle),
@ -141,7 +141,7 @@ pub async fn save(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
pub async fn ranks(ctx: &Context, m: &Message) -> CommandResult { pub async fn ranks(ctx: &Context, m: &Message) -> CommandResult {
let data = ctx.data.read().await; let data = ctx.data.read().await;
let everyone = { let everyone = {
let db = CfSavedUsers::open(&*data); let db = CfSavedUsers::open(&data);
let db = db.borrow()?; let db = db.borrow()?;
db.iter().map(|(k, v)| (*k, v.clone())).collect::<Vec<_>>() db.iter().map(|(k, v)| (*k, v.clone())).collect::<Vec<_>>()
}; };
@ -254,7 +254,7 @@ pub async fn contestranks(ctx: &Context, m: &Message, mut args: Args) -> Command
let contest_id: u64 = args.single()?; let contest_id: u64 = args.single()?;
let guild = m.guild_id.unwrap(); // Guild-only command let guild = m.guild_id.unwrap(); // Guild-only command
let member_cache = data.get::<MemberCache>().unwrap(); let member_cache = data.get::<MemberCache>().unwrap();
let members = CfSavedUsers::open(&*data).borrow()?.clone(); let members = CfSavedUsers::open(&data).borrow()?.clone();
let members = members let members = members
.into_iter() .into_iter()
.map(|(user_id, cf_user)| { .map(|(user_id, cf_user)| {
@ -267,8 +267,8 @@ pub async fn contestranks(ctx: &Context, m: &Message, mut args: Args) -> Command
.collect::<HashMap<_, _>>() .collect::<HashMap<_, _>>()
.await; .await;
let http = data.get::<CFClient>().unwrap(); let http = data.get::<CFClient>().unwrap();
let (contest, problems, ranks) = Contest::standings(&*http, contest_id, |f| { let (contest, problems, ranks) = Contest::standings(http, contest_id, |f| {
f.handles(members.iter().map(|(k, _)| k.clone()).collect()) f.handles(members.keys().cloned().collect())
}) })
.await?; .await?;

View file

@ -65,7 +65,7 @@ pub async fn watch_contest(
contest_id: u64, contest_id: u64,
) -> Result<()> { ) -> Result<()> {
let data = ctx.data.read().await; let data = ctx.data.read().await;
let db = CfSavedUsers::open(&*data).borrow()?.clone(); let db = CfSavedUsers::open(&data).borrow()?.clone();
let member_cache = data.get::<member_cache::MemberCache>().unwrap().clone(); let member_cache = data.get::<member_cache::MemberCache>().unwrap().clone();
let watch_data = data.get::<WatchData>().unwrap().clone(); let watch_data = data.get::<WatchData>().unwrap().clone();
@ -130,7 +130,7 @@ pub async fn watch_contest(
let http = data.get::<CFClient>().unwrap(); let http = data.get::<CFClient>().unwrap();
let (mut contest, problems, _) = let (mut contest, problems, _) =
Contest::standings(&*http, contest_id, |f| f.limit(1, 1)).await?; Contest::standings(http, contest_id, |f| f.limit(1, 1)).await?;
// Collect an initial member list. // Collect an initial member list.
// This never changes during the scan. // This never changes during the scan.
let mut member_results: HashMap<UserId, MemberResult> = db let mut member_results: HashMap<UserId, MemberResult> = db
@ -159,9 +159,7 @@ pub async fn watch_contest(
e.content(format!( e.content(format!(
"Youmu is watching contest **{}**, with the following members: {}", "Youmu is watching contest **{}**, with the following members: {}",
contest.name, contest.name,
member_results member_results.values().map(|m| serenity::utils::MessageBuilder::new()
.iter()
.map(|(_, m)| serenity::utils::MessageBuilder::new()
.push_safe(m.member.distinct()) .push_safe(m.member.distinct())
.push(" (") .push(" (")
.push_mono_safe(&m.handle) .push_mono_safe(&m.handle)
@ -175,7 +173,7 @@ pub async fn watch_contest(
msg.pin(ctx).await.ok(); msg.pin(ctx).await.ok();
loop { loop {
if let Ok(messages) = scan_changes(&*http, &mut member_results, &mut contest).await { if let Ok(messages) = scan_changes(http, &mut member_results, &mut contest).await {
for message in messages { for message in messages {
channel channel
.send_message(&ctx, |e| { .send_message(&ctx, |e| {
@ -204,7 +202,7 @@ pub async fn watch_contest(
ranks.sort_by(|(_, _, a), (_, _, b)| a.rank.cmp(&b.rank)); ranks.sort_by(|(_, _, a), (_, _, b)| a.rank.cmp(&b.rank));
msg.unpin(ctx).await.ok(); msg.unpin(ctx).await.ok();
crate::contest_rank_table(&ctx, &msg, contest, problems, ranks).await?; crate::contest_rank_table(ctx, &msg, contest, problems, ranks).await?;
Ok(()) Ok(())
} }
@ -230,7 +228,7 @@ async fn scan_changes(
.iter() .iter()
.map(|(_, h)| h.handle.clone()) .map(|(_, h)| h.handle.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Contest::standings(&http, contest.id, |f| f.handles(handles)).await? Contest::standings(http, contest.id, |f| f.handles(handles)).await?
}; };
// Change of phase. // Change of phase.
if contest.phase != updated_contest.phase { if contest.phase != updated_contest.phase {
@ -282,7 +280,7 @@ async fn scan_changes(
.iter() .iter()
.zip(row.problem_results.iter()), .zip(row.problem_results.iter()),
) { ) {
if let Some(message) = analyze_change(&contest, old, new).map(|c| { if let Some(message) = analyze_change(contest, old, new).map(|c| {
translate_change( translate_change(
contest.phase, contest.phase,
member_result.handle.as_str(), member_result.handle.as_str(),

View file

@ -32,7 +32,7 @@ pub async fn soft_ban(ctx: &Context, msg: &Message, mut args: Args) -> CommandRe
.guild_id .guild_id
.ok_or_else(|| Error::msg("Command is guild only"))?; .ok_or_else(|| Error::msg("Command is guild only"))?;
let mut db = SoftBans::open(&*data); let mut db = SoftBans::open(&data);
let val = db let val = db
.borrow()? .borrow()?
.get(&guild) .get(&guild)
@ -85,13 +85,13 @@ pub async fn soft_ban(ctx: &Context, msg: &Message, mut args: Args) -> CommandRe
pub async fn soft_ban_init(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { pub async fn soft_ban_init(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
let role_id = args.single::<RoleId>()?; let role_id = args.single::<RoleId>()?;
let data = ctx.data.read().await; let data = ctx.data.read().await;
let guild = msg.guild(&ctx).unwrap(); let guild = msg.guild(ctx).unwrap();
// Check whether the role_id is the one we wanted // Check whether the role_id is the one we wanted
if !guild.roles.contains_key(&role_id) { if !guild.roles.contains_key(&role_id) {
return Err(Error::msg(format!("{} is not a role in this server.", role_id)).into()); return Err(Error::msg(format!("{} is not a role in this server.", role_id)).into());
} }
// Check if we already set up // Check if we already set up
let mut db = SoftBans::open(&*data); let mut db = SoftBans::open(&data);
let set_up = db.borrow()?.contains_key(&guild.id); let set_up = db.borrow()?.contains_key(&guild.id);
if !set_up { if !set_up {
@ -111,7 +111,7 @@ pub async fn watch_soft_bans(cache_http: Arc<CacheAndHttp>, data: AppData) {
{ {
// Poll the data for any changes. // Poll the data for any changes.
let data = data.read().await; let data = data.read().await;
let mut data = SoftBans::open(&*data); let mut data = SoftBans::open(&data);
let mut db = data.borrow().unwrap().clone(); let mut db = data.borrow().unwrap().clone();
let now = Utc::now(); let now = Utc::now();
for (server_id, bans) in db.iter_mut() { for (server_id, bans) in db.iter_mut() {
@ -131,7 +131,7 @@ pub async fn watch_soft_bans(cache_http: Arc<CacheAndHttp>, data: AppData) {
.map(|user_id| { .map(|user_id| {
bans.periodical_bans.remove(&user_id); bans.periodical_bans.remove(&user_id);
lift_soft_ban_for( lift_soft_ban_for(
&*cache_http, &cache_http,
*server_id, *server_id,
&server_name[..], &server_name[..],
bans.role, bans.role,

View file

@ -62,7 +62,7 @@ pub async fn choose(ctx: &Context, m: &Message, mut args: Args) -> CommandResult
let online_only = !flags.contains("everyone"); let online_only = !flags.contains("everyone");
let users: Result<Vec<_>, Error> = { let users: Result<Vec<_>, Error> = {
let guild = m.guild(&ctx).unwrap(); let guild = m.guild(ctx).unwrap();
let presences = &guild.presences; let presences = &guild.presences;
let channel = m.channel_id.to_channel(&ctx).await?; let channel = m.channel_id.to_channel(&ctx).await?;
if let Channel::Guild(channel) = channel { if let Channel::Guild(channel) = channel {

View file

@ -19,7 +19,7 @@ pub use reaction_watcher::Watchers as ReactionWatchers;
async fn list(ctx: &Context, m: &Message, _: Args) -> CommandResult { async fn list(ctx: &Context, m: &Message, _: Args) -> CommandResult {
let guild_id = m.guild_id.unwrap(); // only_in(guilds) let guild_id = m.guild_id.unwrap(); // only_in(guilds)
let data = ctx.data.read().await; let data = ctx.data.read().await;
let db = DB::open(&*data); let db = DB::open(&data);
let roles = db let roles = db
.borrow()? .borrow()?
.get(&guild_id) .get(&guild_id)
@ -190,7 +190,7 @@ async fn add(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
m.reply(&ctx, "No such role exists").await?; m.reply(&ctx, "No such role exists").await?;
} }
Some(role) => { Some(role) => {
DB::open(&*data) DB::open(&data)
.borrow_mut()? .borrow_mut()?
.entry(guild_id) .entry(guild_id)
.or_default() .or_default()
@ -227,7 +227,7 @@ async fn remove(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
m.reply(&ctx, "No such role exists").await?; m.reply(&ctx, "No such role exists").await?;
} }
Some(role) Some(role)
if !DB::open(&*data) if !DB::open(&data)
.borrow()? .borrow()?
.get(&guild_id) .get(&guild_id)
.map(|g| g.roles.contains_key(&role.id)) .map(|g| g.roles.contains_key(&role.id))
@ -237,7 +237,7 @@ async fn remove(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
.await?; .await?;
} }
Some(role) => { Some(role) => {
DB::open(&*data) DB::open(&data)
.borrow_mut()? .borrow_mut()?
.entry(guild_id) .entry(guild_id)
.or_default() .or_default()
@ -289,7 +289,7 @@ async fn parse(
let title = args.single_quoted::<String>().unwrap(); let title = args.single_quoted::<String>().unwrap();
let data = ctx.data.read().await; let data = ctx.data.read().await;
let guild_id = m.guild_id.unwrap(); let guild_id = m.guild_id.unwrap();
let assignables = DB::open(&*data) let assignables = DB::open(&data)
.borrow()? .borrow()?
.get(&guild_id) .get(&guild_id)
.filter(|v| !v.roles.is_empty()) .filter(|v| !v.roles.is_empty())
@ -369,7 +369,7 @@ async fn updaterolemessage(ctx: &Context, m: &Message, args: Args) -> CommandRes
{ {
data.get::<ReactionWatchers>() data.get::<ReactionWatchers>()
.unwrap() .unwrap()
.setup(&mut *message, ctx.clone(), guild_id, title, roles) .setup(&mut message, ctx.clone(), guild_id, title, roles)
.await?; .await?;
} else { } else {
m.reply(&ctx, "Message does not come with a reaction handler") m.reply(&ctx, "Message does not come with a reaction handler")
@ -436,7 +436,7 @@ mod reaction_watcher {
impl Watchers { impl Watchers {
pub fn new(data: &TypeMap) -> Result<Self> { pub fn new(data: &TypeMap) -> Result<Self> {
let init = Roles::open(&*data) let init = Roles::open(data)
.borrow()? .borrow()?
.iter() .iter()
.flat_map(|(&guild, rs)| { .flat_map(|(&guild, rs)| {
@ -510,7 +510,7 @@ mod reaction_watcher {
// Store the message into the list. // Store the message into the list.
{ {
let data = ctx.data.read().await; let data = ctx.data.read().await;
Roles::open(&*data) Roles::open(&data)
.borrow_mut()? .borrow_mut()?
.entry(guild) .entry(guild)
.or_default() .or_default()
@ -537,7 +537,7 @@ mod reaction_watcher {
message: MessageId, message: MessageId,
) -> Result<bool> { ) -> Result<bool> {
let data = ctx.data.read().await; let data = ctx.data.read().await;
Roles::open(&*data) Roles::open(&data)
.borrow_mut()? .borrow_mut()?
.entry(guild) .entry(guild)
.or_default() .or_default()
@ -583,7 +583,7 @@ mod reaction_watcher {
} }
}; };
eprintln!("{:?}", reaction); eprintln!("{:?}", reaction);
if let Err(e) = Self::handle_reaction(&ctx, guild, message, &*reaction).await { if let Err(e) = Self::handle_reaction(&ctx, guild, message, &reaction).await {
eprintln!("Handling {:?}: {}", reaction, e); eprintln!("Handling {:?}: {}", reaction, e);
break; break;
} }
@ -610,7 +610,7 @@ mod reaction_watcher {
return Ok(()); return Ok(());
} }
// Get the role list. // Get the role list.
let role = Roles::open(&*data) let role = Roles::open(&data)
.borrow()? .borrow()?
.get(&guild) .get(&guild)
.ok_or_else(|| Error::msg("guild no longer has role list"))? .ok_or_else(|| Error::msg("guild no longer has role list"))?

View file

@ -116,7 +116,7 @@ pub async fn vote(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
// Collect reactions... // Collect reactions...
let user_reactions = panel let user_reactions = panel
.await_reactions(&ctx) .await_reactions(ctx)
.removed(true) .removed(true)
.timeout(*duration) .timeout(*duration)
.build() .build()

View file

@ -64,7 +64,7 @@ pub fn load_role_list(
match legacy::RolesV1::load_from_path(v1_path.as_ref()) { match legacy::RolesV1::load_from_path(v1_path.as_ref()) {
Ok(v1) => { Ok(v1) => {
Roles::insert_into(map, path)?; Roles::insert_into(map, path)?;
*Roles::open(&map).borrow_mut()? = v1 *Roles::open(map).borrow_mut()? = v1
.get_data(true)? .get_data(true)?
.into_iter() .into_iter()
.map(|(guild, roles)| { .map(|(guild, roles)| {

View file

@ -103,7 +103,7 @@ async fn get_image(
// Fix the tags: change whitespaces to + // Fix the tags: change whitespaces to +
let tags = tags.split_whitespace().collect::<Vec<_>>().join("_"); let tags = tags.split_whitespace().collect::<Vec<_>>().join("_");
let req = client let req = client
.get(&format!( .get(format!(
"https://danbooru.donmai.us/posts.json?tags=rating:{}+{}", "https://danbooru.donmai.us/posts.json?tags=rating:{}+{}",
rating.to_string(), rating.to_string(),
tags tags

View file

@ -95,7 +95,7 @@ async fn pick(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
.peekable(); .peekable();
// If we have the first argument as question, use it. // If we have the first argument as question, use it.
let question = match choices.peek() { let question = match choices.peek() {
Some(ref q) if q.starts_with('?') => Some(q.replacen("?", "", 1) + "?"), Some(q) if q.starts_with('?') => Some(q.replacen('?', "", 1) + "?"),
_ => None, _ => None,
}; };
// If we have a question, that's not a choice. // If we have a question, that's not a choice.

View file

@ -125,7 +125,7 @@ impl Announcer {
.iter() .iter()
.filter_map(|u| u.to_event_rank()) .filter_map(|u| u.to_event_rank())
.filter(|u| u.mode == mode && u.date > last_update && u.date <= now) .filter(|u| u.mode == mode && u.date > last_update && u.date <= now)
.map(|ev| CollectedScore::from_event(&*client, &user, ev, user_id, &channels[..])) .map(|ev| CollectedScore::from_event(&client, &user, ev, user_id, &channels[..]))
.collect::<stream::FuturesUnordered<_>>() .collect::<stream::FuturesUnordered<_>>()
.filter_map(|u| future::ready(u.pls_ok())) .filter_map(|u| future::ready(u.pls_ok()))
.collect::<Vec<_>>() .collect::<Vec<_>>()
@ -235,7 +235,7 @@ impl<'a> CollectedScore<'a> {
impl<'a> CollectedScore<'a> { impl<'a> CollectedScore<'a> {
async fn send_message(self, ctx: &Context) -> Result<Vec<Message>> { async fn send_message(self, ctx: &Context) -> Result<Vec<Message>> {
let (bm, content) = self.get_beatmap(&ctx).await?; let (bm, content) = self.get_beatmap(ctx).await?;
self.channels self.channels
.iter() .iter()
.map(|c| self.send_message_to(*c, ctx, &bm, &content)) .map(|c| self.send_message_to(*c, ctx, &bm, &content))
@ -293,7 +293,7 @@ impl<'a> CollectedScore<'a> {
} }
}) })
.embed(|e| { .embed(|e| {
let mut b = score_embed(&self.score, &bm, content, self.user); let mut b = score_embed(&self.score, bm, content, self.user);
match self.kind { match self.kind {
ScoreType::TopRecord(rank) => b.top_record(rank), ScoreType::TopRecord(rank) => b.top_record(rank),
ScoreType::WorldRecord(rank) => b.world_record(rank), ScoreType::WorldRecord(rank) => b.world_record(rank),
@ -302,7 +302,7 @@ impl<'a> CollectedScore<'a> {
}) })
}) })
.await?; .await?;
save_beatmap(&*ctx.data.read().await, channel, &bm) save_beatmap(&*ctx.data.read().await, channel, bm)
.await .await
.pls_ok(); .pls_ok();
Ok(m) Ok(m)

View file

@ -105,7 +105,7 @@ impl BeatmapMetaCache {
// Save each beatmap. // Save each beatmap.
let mut t = self.pool.begin().await?; let mut t = self.pool.begin().await?;
for b in &beatmaps { for b in &beatmaps {
let mut b = Self::to_cached_beatmap(&b, None); let mut b = Self::to_cached_beatmap(b, None);
b.store(&mut t).await?; b.store(&mut t).await?;
// Save the beatmapset mapping. // Save the beatmapset mapping.
b.link_beatmapset(id as i64, &mut t).await?; b.link_beatmapset(id as i64, &mut t).await?;

View file

@ -249,7 +249,7 @@ mod scores {
b.map(|(beatmap, info)| { b.map(|(beatmap, info)| {
format!( format!(
"[{:.1}*] {} - {} [{}] ({})", "[{:.1}*] {} - {} [{}] ({})",
info.map(|i| i.stars as f64) info.map(|i| i.stars)
.unwrap_or(beatmap.difficulty.stars), .unwrap_or(beatmap.difficulty.stars),
beatmap.artist, beatmap.artist,
beatmap.title, beatmap.title,

View file

@ -7,6 +7,8 @@ use serenity::{builder::CreateEmbed, utils::MessageBuilder};
use std::time::Duration; use std::time::Duration;
use youmubot_prelude::*; use youmubot_prelude::*;
type CreateEmbedFn = dyn FnOnce(&mut CreateEmbed) -> &mut CreateEmbed + Send + Sync;
/// Writes a number grouped in groups of 3. /// Writes a number grouped in groups of 3.
pub(crate) fn grouped_number(num: u64) -> String { pub(crate) fn grouped_number(num: u64) -> String {
let s = num.to_string(); let s = num.to_string();
@ -22,7 +24,7 @@ pub(crate) fn grouped_number(num: u64) -> String {
fn beatmap_description(b: &Beatmap) -> String { fn beatmap_description(b: &Beatmap) -> String {
MessageBuilder::new() MessageBuilder::new()
.push_bold_line(&b.approval) .push_bold_line(b.approval)
.push({ .push({
let link = b.download_link(false); let link = b.download_link(false);
format!( format!(
@ -34,9 +36,9 @@ fn beatmap_description(b: &Beatmap) -> String {
}) })
.push_line(format!(" [[Beatmapset]]({})", b.beatmapset_link())) .push_line(format!(" [[Beatmapset]]({})", b.beatmapset_link()))
.push("Language: ") .push("Language: ")
.push_bold(&b.language) .push_bold(b.language)
.push(" | Genre: ") .push(" | Genre: ")
.push_bold_line(&b.genre) .push_bold_line(b.genre)
.push( .push(
b.source b.source
.as_ref() .as_ref()
@ -60,12 +62,12 @@ pub fn beatmap_offline_embed(
b: &'_ crate::discord::oppai_cache::BeatmapContent, b: &'_ crate::discord::oppai_cache::BeatmapContent,
m: Mode, m: Mode,
mods: Mods, mods: Mods,
) -> Result<Box<dyn FnOnce(&mut CreateEmbed) -> &mut CreateEmbed + Send + Sync>> { ) -> Result<Box<CreateEmbedFn>> {
let bm = b.content.clone(); let bm = b.content.clone();
let metadata = b.metadata.clone(); let metadata = b.metadata.clone();
let (info, pp) = b.get_possible_pp_with(m, mods)?; let (info, pp) = b.get_possible_pp_with(m, mods)?;
let total_length = if bm.hit_objects.len() >= 1 { let total_length = if !bm.hit_objects.is_empty() {
Duration::from_millis( Duration::from_millis(
(bm.hit_objects.last().unwrap().end_time() - bm.hit_objects.first().unwrap().start_time) (bm.hit_objects.last().unwrap().end_time() - bm.hit_objects.first().unwrap().start_time)
as u64, as u64,
@ -309,7 +311,7 @@ impl<'a> ScoreEmbedBuilder<'a> {
s.mods, s.mods,
) )
.ok() .ok()
.map(|pp| (pp as f64, format!("{:.2}pp [?]", pp))) .map(|pp| (pp, format!("{:.2}pp [?]", pp)))
}); });
let pp = if !s.perfect { let pp = if !s.perfect {
content content
@ -320,11 +322,7 @@ impl<'a> ScoreEmbedBuilder<'a> {
s.mods, s.mods,
) )
.ok() .ok()
.filter(|&v| { .filter(|&v| pp.as_ref().map(|&(origin, _)| origin < v).unwrap_or(false))
pp.as_ref()
.map(|&(origin, _)| origin < v as f64)
.unwrap_or(false)
})
.and_then(|value| { .and_then(|value| {
pp.as_ref() pp.as_ref()
.map(|(_, original)| format!("{} ({:.2}pp if FC?)", original, value)) .map(|(_, original)| format!("{} ({:.2}pp if FC?)", original, value))
@ -409,7 +407,7 @@ impl<'a> ScoreEmbedBuilder<'a> {
true, true,
) )
.field("Map stats", diff.format_info(mode, s.mods, b), false); .field("Map stats", diff.format_info(mode, s.mods, b), false);
let mut footer = self.footer.take().unwrap_or_else(String::new); let mut footer = self.footer.take().unwrap_or_default();
if mode != Mode::Std && s.mods != Mods::NOMOD { if mode != Mode::Std && s.mods != Mods::NOMOD {
footer += " Star difficulty does not reflect game mods."; footer += " Star difficulty does not reflect game mods.";
} }
@ -501,9 +499,9 @@ pub(crate) fn user_embed(
.push(format!( .push(format!(
"> {}", "> {}",
map.difficulty map.difficulty
.apply_mods(v.mods, info.stars as f64) .apply_mods(v.mods, info.stars)
.format_info(mode, v.mods, &map) .format_info(mode, v.mods, &map)
.replace("\n", "\n> ") .replace('\n', "\n> ")
)) ))
.build(), .build(),
false, false,

View file

@ -60,7 +60,7 @@ pub fn dot_osu_hook<'a>(
} }
}) })
.collect::<stream::FuturesUnordered<_>>() .collect::<stream::FuturesUnordered<_>>()
.filter_map(|v| future::ready(v)) .filter_map(future::ready)
.collect::<Vec<_>>() .collect::<Vec<_>>()
.await; .await;
@ -96,14 +96,14 @@ pub fn dot_osu_hook<'a>(
} }
}) })
.collect::<stream::FuturesUnordered<_>>() .collect::<stream::FuturesUnordered<_>>()
.filter_map(|v| future::ready(v)) .filter_map(future::ready)
.filter(|v| future::ready(v.len() > 0)) .filter(|v| future::ready(!v.is_empty()))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.await .await
.concat(); .concat();
osu_embeds.extend(osz_embeds); osu_embeds.extend(osz_embeds);
if osu_embeds.len() > 0 { if !osu_embeds.is_empty() {
msg.channel_id msg.channel_id
.send_message(ctx, |f| { .send_message(ctx, |f| {
f.reference_message(msg) f.reference_message(msg)
@ -129,7 +129,7 @@ pub fn hook<'a>(
let (old_links, new_links, short_links) = ( let (old_links, new_links, short_links) = (
handle_old_links(ctx, &msg.content), handle_old_links(ctx, &msg.content),
handle_new_links(ctx, &msg.content), handle_new_links(ctx, &msg.content),
handle_short_links(ctx, &msg, &msg.content), handle_short_links(ctx, msg, &msg.content),
); );
stream::select(old_links, stream::select(new_links, short_links)) stream::select(old_links, stream::select(new_links, short_links))
.then(|l| async move { .then(|l| async move {
@ -139,7 +139,7 @@ pub fn hook<'a>(
.await .await
.pls_ok(); .pls_ok();
let mode = l.mode.unwrap_or(b.mode); let mode = l.mode.unwrap_or(b.mode);
let bm = super::BeatmapWithMode(b, mode); let bm = super::BeatmapWithMode(*b, mode);
crate::discord::cache::save_beatmap( crate::discord::cache::save_beatmap(
&*ctx.data.read().await, &*ctx.data.read().await,
msg.channel_id, msg.channel_id,
@ -163,7 +163,7 @@ pub fn hook<'a>(
} }
enum EmbedType { enum EmbedType {
Beatmap(Beatmap, BeatmapInfoWithPP, Mods), Beatmap(Box<Beatmap>, BeatmapInfoWithPP, Mods),
Beatmapset(Vec<Beatmap>), Beatmapset(Vec<Beatmap>),
} }
@ -210,12 +210,11 @@ fn handle_old_links<'a>(
} }
let r: Result<_> = Ok(match req_type { let r: Result<_> = Ok(match req_type {
"b" => { "b" => {
let b = beatmaps.into_iter().next().unwrap(); let b = Box::new(beatmaps.into_iter().next().unwrap());
// collect beatmap info // collect beatmap info
let mods = capture let mods = capture
.name("mods") .name("mods")
.map(|v| Mods::from_str(v.as_str()).pls_ok()) .and_then(|v| Mods::from_str(v.as_str()).pls_ok())
.flatten()
.unwrap_or(Mods::NOMOD); .unwrap_or(Mods::NOMOD);
let info = { let info = {
let mode = mode.unwrap_or(b.mode); let mode = mode.unwrap_or(b.mode);
@ -280,7 +279,7 @@ fn handle_new_links<'a>(
} }
let r: Result<_> = Ok(match capture.name("beatmap_id") { let r: Result<_> = Ok(match capture.name("beatmap_id") {
Some(_) => { Some(_) => {
let beatmap = beatmaps.into_iter().next().unwrap(); let beatmap = Box::new(beatmaps.into_iter().next().unwrap());
// collect beatmap info // collect beatmap info
let mods = capture let mods = capture
.name("mods") .name("mods")
@ -359,7 +358,7 @@ fn handle_short_links<'a>(
.and_then(|b| b.get_possible_pp_with(mode, mods))? .and_then(|b| b.get_possible_pp_with(mode, mods))?
}; };
let r: Result<_> = Ok(ToPrint { let r: Result<_> = Ok(ToPrint {
embed: EmbedType::Beatmap(beatmap, info, mods), embed: EmbedType::Beatmap(Box::new(beatmap), info, mods),
link: capture.name("main").unwrap().as_str(), link: capture.name("main").unwrap().as_str(),
mode, mode,
}); });
@ -410,7 +409,7 @@ async fn handle_beatmapset<'a, 'b>(
reply_to: &Message, reply_to: &Message,
) -> Result<()> { ) -> Result<()> {
crate::discord::display::display_beatmapset( crate::discord::display::display_beatmapset(
&ctx, ctx,
beatmaps, beatmaps,
mode, mode,
None, None,

View file

@ -207,7 +207,7 @@ pub async fn save(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
.await?; .await?;
return Ok(()); return Ok(());
} }
add_user(msg.author.id, u.id, &*data).await?; add_user(msg.author.id, u.id, &data).await?;
msg.reply( msg.reply(
&ctx, &ctx,
MessageBuilder::new() MessageBuilder::new()
@ -239,7 +239,7 @@ pub async fn forcesave(ctx: &Context, msg: &Message, mut args: Args) -> CommandR
let user: Option<User> = osu.user(UserID::Auto(user), |f| f).await?; let user: Option<User> = osu.user(UserID::Auto(user), |f| f).await?;
match user { match user {
Some(u) => { Some(u) => {
add_user(target, u.id, &*data).await?; add_user(target, u.id, &data).await?;
msg.reply( msg.reply(
&ctx, &ctx,
MessageBuilder::new() MessageBuilder::new()
@ -335,7 +335,7 @@ pub async fn recent(ctx: &Context, msg: &Message, mut args: Args) -> CommandResu
let mode = args.single::<ModeArg>().unwrap_or(ModeArg(Mode::Std)).0; let mode = args.single::<ModeArg>().unwrap_or(ModeArg(Mode::Std)).0;
let user = to_user_id_query( let user = to_user_id_query(
args.quoted().trimmed().single::<UsernameArg>().ok(), args.quoted().trimmed().single::<UsernameArg>().ok(),
&*data, &data,
msg, msg,
) )
.await?; .await?;
@ -370,7 +370,7 @@ pub async fn recent(ctx: &Context, msg: &Message, mut args: Args) -> CommandResu
.await?; .await?;
// Save the beatmap... // Save the beatmap...
cache::save_beatmap(&*data, msg.channel_id, &beatmap_mode).await?; cache::save_beatmap(&data, msg.channel_id, &beatmap_mode).await?;
} }
Nth::All => { Nth::All => {
let plays = osu let plays = osu
@ -409,7 +409,7 @@ pub(crate) async fn load_beatmap(
replied.embeds.iter().find_map(|e| { replied.embeds.iter().find_map(|e| {
e.description e.description
.as_ref() .as_ref()
.and_then(|v| SHORT_LINK_REGEX.captures(&v)) .and_then(|v| SHORT_LINK_REGEX.captures(v))
.or_else(|| { .or_else(|| {
e.fields e.fields
.iter() .iter()
@ -432,10 +432,10 @@ pub(crate) async fn load_beatmap(
.ok() .ok()
.and_then(|v| v.into_iter().next()); .and_then(|v| v.into_iter().next());
if let Some(beatmap) = bms { if let Some(beatmap) = bms {
let bm_mode = beatmap.mode.clone(); let bm_mode = beatmap.mode;
let bm = BeatmapWithMode(beatmap, mode.unwrap_or(bm_mode)); let bm = BeatmapWithMode(beatmap, mode.unwrap_or(bm_mode));
// Store the beatmap in history // Store the beatmap in history
cache::save_beatmap(&*data, msg.channel_id, &bm) cache::save_beatmap(&data, msg.channel_id, &bm)
.await .await
.pls_ok(); .pls_ok();
@ -444,7 +444,7 @@ pub(crate) async fn load_beatmap(
} }
} }
let b = cache::get_beatmap(&*data, msg.channel_id) let b = cache::get_beatmap(&data, msg.channel_id)
.await .await
.ok() .ok()
.flatten(); .flatten();
@ -529,7 +529,7 @@ pub async fn check(ctx: &Context, msg: &Message, mut args: Args) -> CommandResul
None => Some(msg.author.id), None => Some(msg.author.id),
_ => None, _ => None,
}; };
let user = to_user_id_query(username_arg, &*data, msg).await?; let user = to_user_id_query(username_arg, &data, msg).await?;
let osu = data.get::<OsuClient>().unwrap(); let osu = data.get::<OsuClient>().unwrap();
@ -581,7 +581,7 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
.map(|ModeArg(t)| t) .map(|ModeArg(t)| t)
.unwrap_or(Mode::Std); .unwrap_or(Mode::Std);
let user = to_user_id_query(args.single::<UsernameArg>().ok(), &*data, msg).await?; let user = to_user_id_query(args.single::<UsernameArg>().ok(), &data, msg).await?;
let meta_cache = data.get::<BeatmapMetaCache>().unwrap(); let meta_cache = data.get::<BeatmapMetaCache>().unwrap();
let osu = data.get::<OsuClient>().unwrap(); let osu = data.get::<OsuClient>().unwrap();
@ -622,7 +622,7 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
.await?; .await?;
// Save the beatmap... // Save the beatmap...
cache::save_beatmap(&*data, msg.channel_id, &beatmap).await?; cache::save_beatmap(&data, msg.channel_id, &beatmap).await?;
} }
Nth::All => { Nth::All => {
let plays = osu let plays = osu
@ -636,7 +636,7 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
async fn get_user(ctx: &Context, msg: &Message, mut args: Args, mode: Mode) -> CommandResult { async fn get_user(ctx: &Context, msg: &Message, mut args: Args, mode: Mode) -> CommandResult {
let data = ctx.data.read().await; let data = ctx.data.read().await;
let user = to_user_id_query(args.single::<UsernameArg>().ok(), &*data, msg).await?; let user = to_user_id_query(args.single::<UsernameArg>().ok(), &data, msg).await?;
let osu = data.get::<OsuClient>().unwrap(); let osu = data.get::<OsuClient>().unwrap();
let cache = data.get::<BeatmapMetaCache>().unwrap(); let cache = data.get::<BeatmapMetaCache>().unwrap();
let user = osu.user(user, |f| f.mode(mode)).await?; let user = osu.user(user, |f| f.mode(mode)).await?;

View file

@ -42,9 +42,9 @@ pub enum Accuracy {
ByValue(f64, u64), ByValue(f64, u64),
} }
impl Into<f64> for Accuracy { impl From<Accuracy> for f64 {
fn into(self) -> f64 { fn from(val: Accuracy) -> Self {
match self { match val {
Accuracy::ByValue(v, _) => v, Accuracy::ByValue(v, _) => v,
Accuracy::ByCount(n300, n100, n50, nmiss) => { Accuracy::ByCount(n300, n100, n50, nmiss) => {
100.0 * ((6 * n300 + 2 * n100 + n50) as f64) 100.0 * ((6 * n300 + 2 * n100 + n50) as f64)
@ -396,10 +396,10 @@ impl BeatmapCache {
} }
async fn get_beatmap_db(&self, id: u64) -> Result<Option<BeatmapContent>> { async fn get_beatmap_db(&self, id: u64) -> Result<Option<BeatmapContent>> {
Ok(models::CachedBeatmapContent::by_id(id as i64, &self.pool) models::CachedBeatmapContent::by_id(id as i64, &self.pool)
.await? .await?
.map(|v| Self::parse_beatmap(String::from_utf8(v.content)?)) .map(|v| Self::parse_beatmap(String::from_utf8(v.content)?))
.transpose()?) .transpose()
} }
/// Get a beatmap from the cache. /// Get a beatmap from the cache.

View file

@ -367,7 +367,7 @@ async fn show_leaderboard(
return Box::pin(future::ready(Ok(false))); return Box::pin(future::ready(Ok(false)));
} }
let total_len = scores.len(); let total_len = scores.len();
let scores = (&scores[start..end]).to_vec(); let scores = scores[start..end].to_vec();
let bm = (bm.0.clone(), bm.1); let bm = (bm.0.clone(), bm.1);
Box::pin(async move { Box::pin(async move {
// username width // username width

View file

@ -58,7 +58,7 @@ impl Client {
) -> Result<Vec<Beatmap>> { ) -> Result<Vec<Beatmap>> {
let mut r = BeatmapRequestBuilder::new(kind); let mut r = BeatmapRequestBuilder::new(kind);
f(&mut r); f(&mut r);
let res: Vec<raw::Beatmap> = r.build(&self).await?.json().await?; let res: Vec<raw::Beatmap> = r.build(self).await?.json().await?;
Ok(vec_try_into(res)?) Ok(vec_try_into(res)?)
} }
@ -69,7 +69,7 @@ impl Client {
) -> Result<Option<User>, Error> { ) -> Result<Option<User>, Error> {
let mut r = UserRequestBuilder::new(user); let mut r = UserRequestBuilder::new(user);
f(&mut r); f(&mut r);
let res: Vec<raw::User> = r.build(&self).await?.json().await?; let res: Vec<raw::User> = r.build(self).await?.json().await?;
let res = vec_try_into(res)?; let res = vec_try_into(res)?;
Ok(res.into_iter().next()) Ok(res.into_iter().next())
} }
@ -81,7 +81,7 @@ impl Client {
) -> Result<Vec<Score>, Error> { ) -> Result<Vec<Score>, Error> {
let mut r = ScoreRequestBuilder::new(beatmap_id); let mut r = ScoreRequestBuilder::new(beatmap_id);
f(&mut r); f(&mut r);
let res: Vec<raw::Score> = r.build(&self).await?.json().await?; let res: Vec<raw::Score> = r.build(self).await?.json().await?;
let mut res: Vec<Score> = vec_try_into(res)?; let mut res: Vec<Score> = vec_try_into(res)?;
// with a scores request you need to fill the beatmap ids yourself // with a scores request you need to fill the beatmap ids yourself
@ -115,7 +115,7 @@ impl Client {
) -> Result<Vec<Score>, Error> { ) -> Result<Vec<Score>, Error> {
let mut r = UserScoreRequestBuilder::new(u, user); let mut r = UserScoreRequestBuilder::new(u, user);
f(&mut r); f(&mut r);
let res: Vec<raw::Score> = r.build(&self).await?.json().await?; let res: Vec<raw::Score> = r.build(self).await?.json().await?;
let res = vec_try_into(res)?; let res = vec_try_into(res)?;
Ok(res) Ok(res)
} }

View file

@ -279,7 +279,7 @@ fn parse_date(date: impl AsRef<str>) -> ParseResult<DateTime<Utc>> {
parse( parse(
&mut parsed, &mut parsed,
date.as_ref(), date.as_ref(),
(&[ [
Item::Numeric(Numeric::Year, Pad::Zero), Item::Numeric(Numeric::Year, Pad::Zero),
Item::Literal("-"), Item::Literal("-"),
Item::Numeric(Numeric::Month, Pad::Zero), Item::Numeric(Numeric::Month, Pad::Zero),
@ -291,7 +291,7 @@ fn parse_date(date: impl AsRef<str>) -> ParseResult<DateTime<Utc>> {
Item::Numeric(Numeric::Minute, Pad::Zero), Item::Numeric(Numeric::Minute, Pad::Zero),
Item::Literal(":"), Item::Literal(":"),
Item::Numeric(Numeric::Second, Pad::Zero), Item::Numeric(Numeric::Second, Pad::Zero),
]) ]
.iter(), .iter(),
) )
.map_err(ParseError::DateParseError)?; .map_err(ParseError::DateParseError)?;

View file

@ -9,7 +9,7 @@ fn parse_beatmaps() {
parse_str::<Vec<RawBeatmap>>(INPUT) parse_str::<Vec<RawBeatmap>>(INPUT)
.unwrap() .unwrap()
.into_iter() .into_iter()
.map(|v| Beatmap::try_from(v)) .map(Beatmap::try_from)
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.unwrap(); .unwrap();
} }

View file

@ -159,7 +159,7 @@ impl AnnouncerHandler {
let after = tokio::time::sleep_until(tokio::time::Instant::now() + cooldown); let after = tokio::time::sleep_until(tokio::time::Instant::now() + cooldown);
join_all(self.announcers.iter().map(|(key, announcer)| { join_all(self.announcers.iter().map(|(key, announcer)| {
eprintln!(" - scanning key `{}`", key); eprintln!(" - scanning key `{}`", key);
Self::announce(self.data.clone(), self.cache_http.clone(), *key, announcer).map( Self::announce(self.data.clone(), self.cache_http.clone(), key, announcer).map(
move |v| { move |v| {
if let Err(e) = v { if let Err(e) = v {
eprintln!(" - key `{}`: {:?}", *key, e) eprintln!(" - key `{}`: {:?}", *key, e)
@ -241,9 +241,9 @@ pub async fn register_announcer(ctx: &Context, m: &Message, mut args: Args) -> C
.await?; .await?;
return Ok(()); return Ok(());
} }
let guild = m.guild(&ctx).expect("Guild-only command"); let guild = m.guild(ctx).expect("Guild-only command");
let channel = m.channel_id.to_channel(&ctx).await?; let channel = m.channel_id.to_channel(&ctx).await?;
AnnouncerChannels::open(&*data) AnnouncerChannels::open(&data)
.borrow_mut()? .borrow_mut()?
.entry(key.clone()) .entry(key.clone())
.or_default() .or_default()
@ -284,8 +284,8 @@ pub async fn remove_announcer(ctx: &Context, m: &Message, mut args: Args) -> Com
.await?; .await?;
return Ok(()); return Ok(());
} }
let guild = m.guild(&ctx).expect("Guild-only command"); let guild = m.guild(ctx).expect("Guild-only command");
AnnouncerChannels::open(&*data) AnnouncerChannels::open(&data)
.borrow_mut()? .borrow_mut()?
.entry(key.clone()) .entry(key.clone())
.and_modify(|m| { .and_modify(|m| {

View file

@ -138,12 +138,12 @@ mod duration {
let tests = [ let tests = [
( (
"2D2h1m", "2D2h1m",
StdDuration::from_secs(2 * 60 * 60 * 24 + 2 * 60 * 60 + 1 * 60), StdDuration::from_secs(2 * 60 * 60 * 24 + 2 * 60 * 60 + 60),
), ),
( (
"1W2D3h4m5s", "1W2D3h4m5s",
StdDuration::from_secs( StdDuration::from_secs(
1 * 7 * 24 * 60 * 60 + // 1W 7 * 24 * 60 * 60 + // 1W
2 * 24 * 60 * 60 + // 2D 2 * 24 * 60 * 60 + // 2D
3 * 60 * 60 + // 3h 3 * 60 * 60 + // 3h
4 * 60 + // 4m 4 * 60 + // 4m
@ -153,7 +153,7 @@ mod duration {
( (
"1W2D3h4m5s6W", "1W2D3h4m5s6W",
StdDuration::from_secs( StdDuration::from_secs(
1 * 7 * 24 * 60 * 60 + // 1W 7 * 24 * 60 * 60 + // 1W
2 * 24 * 60 * 60 + // 2D 2 * 24 * 60 * 60 + // 2D
3 * 60 * 60 + // 3h 3 * 60 * 60 + // 3h
4 * 60 + // 4m 4 * 60 + // 4m

View file

@ -23,7 +23,7 @@ impl Flags {
pub fn collect_from(args: &mut Args) -> Flags { pub fn collect_from(args: &mut Args) -> Flags {
let mut set = Set::new(); let mut set = Set::new();
loop { loop {
if let Some(Flag(s)) = args.find().ok() { if let Ok(Flag(s)) = args.find() {
set.insert(s); set.insert(s);
} else { } else {
break Flags(set); break Flags(set);

View file

@ -102,7 +102,7 @@ async fn paginate_with_first_message(
mut message: Message, mut message: Message,
timeout: std::time::Duration, timeout: std::time::Duration,
) -> Result<()> { ) -> Result<()> {
pager.prerender(&ctx, &mut message).await?; pager.prerender(ctx, &mut message).await?;
pager.render(0, ctx, &mut message).await?; pager.render(0, ctx, &mut message).await?;
// Just quit if there is only one page // Just quit if there is only one page
if pager.len().filter(|&v| v == 1).is_some() { if pager.len().filter(|&v| v == 1).is_some() {
@ -127,7 +127,7 @@ async fn paginate_with_first_message(
.await?; .await?;
} }
// Build a reaction collector // Build a reaction collector
let mut reaction_collector = message.await_reactions(&ctx).removed(true).build(); let mut reaction_collector = message.await_reactions(ctx).removed(true).build();
let mut page = 0; let mut page = 0;
// Loop the handler function. // Loop the handler function.

View file

@ -61,7 +61,7 @@ impl EventHandler for Handler {
async fn is_not_channel_mod(ctx: &Context, msg: &Message) -> bool { async fn is_not_channel_mod(ctx: &Context, msg: &Message) -> bool {
match msg.channel_id.to_channel(&ctx).await { match msg.channel_id.to_channel(&ctx).await {
Ok(Channel::Guild(gc)) => gc Ok(Channel::Guild(gc)) => gc
.permissions_for_user(&ctx, msg.author.id) .permissions_for_user(ctx, msg.author.id)
.map(|perms| !perms.contains(Permissions::MANAGE_MESSAGES)) .map(|perms| !perms.contains(Permissions::MANAGE_MESSAGES))
.unwrap_or(true), .unwrap_or(true),
_ => true, _ => true,
@ -173,7 +173,7 @@ async fn setup_framework(token: &str) -> StandardFramework {
c.with_whitespace(false) c.with_whitespace(false)
.prefixes( .prefixes(
var("PREFIX") var("PREFIX")
.map(|v| v.split(",").map(|v| v.trim().to_owned()).collect()) .map(|v| v.split(',').map(|v| v.trim().to_owned()).collect())
.unwrap_or_else(|_| vec!["y!".to_owned(), "y2!".to_owned()]), .unwrap_or_else(|_| vec!["y!".to_owned(), "y2!".to_owned()]),
) )
.delimiters(vec![" / ", "/ ", " /", "/"]) .delimiters(vec![" / ", "/ ", " /", "/"])