mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-05-24 17:20:49 +00:00
Core/Prelude: Fix lifetime unsoundness
This commit is contained in:
parent
c672a8836c
commit
f1719019d1
9 changed files with 150 additions and 112 deletions
|
@ -41,10 +41,7 @@ pub async fn choose(ctx: &Context, m: &Message, mut args: Args) -> CommandResult
|
|||
} else {
|
||||
args.single::<String>()?
|
||||
};
|
||||
let role = match args.single::<RoleId>().ok() {
|
||||
Some(v) => v.to_role_cached(&ctx).await,
|
||||
None => None,
|
||||
};
|
||||
let role = args.single::<RoleId>().ok();
|
||||
|
||||
let users: Result<Vec<_>, Error> = {
|
||||
let guild = m.guild(&ctx).await.unwrap();
|
||||
|
@ -68,16 +65,21 @@ pub async fn choose(ctx: &Context, m: &Message, mut args: Args) -> CommandResult
|
|||
})
|
||||
.map(|mem| future::ready(mem))
|
||||
.collect::<stream::FuturesUnordered<_>>()
|
||||
.filter(|member| async {
|
||||
.filter_map(|member| async move {
|
||||
// Filter by role if provided
|
||||
if let Some(role) = role {
|
||||
member
|
||||
if member
|
||||
.roles(&ctx)
|
||||
.await
|
||||
.map(|roles| roles.into_iter().any(|r| role.id == r.id))
|
||||
.map(|roles| roles.into_iter().any(|r| role == r.id))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
Some(member)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
true
|
||||
Some(member)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
|
|
@ -34,66 +34,69 @@ async fn list(ctx: &Context, m: &Message, _: Args) -> CommandResult {
|
|||
let pages = (roles.len() + ROLES_PER_PAGE - 1) / ROLES_PER_PAGE;
|
||||
|
||||
paginate(
|
||||
|page, ctx, msg| async move {
|
||||
let page = page as usize;
|
||||
let start = page * ROLES_PER_PAGE;
|
||||
let end = roles.len().min(start + ROLES_PER_PAGE);
|
||||
if end <= start {
|
||||
return Ok(false);
|
||||
}
|
||||
let roles = &roles[start..end];
|
||||
let nw = roles // name width
|
||||
.iter()
|
||||
.map(|(r, _)| r.name.len())
|
||||
.max()
|
||||
.unwrap()
|
||||
.max(6);
|
||||
let idw = roles[0].0.id.to_string().len();
|
||||
let dw = roles
|
||||
.iter()
|
||||
.map(|v| v.1.len())
|
||||
.max()
|
||||
.unwrap()
|
||||
.max(" Description ".len());
|
||||
let mut m = MessageBuilder::new();
|
||||
m.push_line("```");
|
||||
|page, ctx, msg| {
|
||||
let roles = roles.clone();
|
||||
Box::pin(async move {
|
||||
let page = page as usize;
|
||||
let start = page * ROLES_PER_PAGE;
|
||||
let end = roles.len().min(start + ROLES_PER_PAGE);
|
||||
if end <= start {
|
||||
return Ok(false);
|
||||
}
|
||||
let roles = &roles[start..end];
|
||||
let nw = roles // name width
|
||||
.iter()
|
||||
.map(|(r, _)| r.name.len())
|
||||
.max()
|
||||
.unwrap()
|
||||
.max(6);
|
||||
let idw = roles[0].0.id.to_string().len();
|
||||
let dw = roles
|
||||
.iter()
|
||||
.map(|v| v.1.len())
|
||||
.max()
|
||||
.unwrap()
|
||||
.max(" Description ".len());
|
||||
let mut m = MessageBuilder::new();
|
||||
m.push_line("```");
|
||||
|
||||
// Table header
|
||||
m.push_line(format!(
|
||||
"{:nw$} | {:idw$} | {:dw$}",
|
||||
"Name",
|
||||
"ID",
|
||||
"Description",
|
||||
nw = nw,
|
||||
idw = idw,
|
||||
dw = dw,
|
||||
));
|
||||
m.push_line(format!(
|
||||
"{:->nw$}---{:->idw$}---{:->dw$}",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
nw = nw,
|
||||
idw = idw,
|
||||
dw = dw,
|
||||
));
|
||||
|
||||
for (role, description) in roles.iter() {
|
||||
// Table header
|
||||
m.push_line(format!(
|
||||
"{:nw$} | {:idw$} | {:dw$}",
|
||||
role.name,
|
||||
role.id,
|
||||
description,
|
||||
"Name",
|
||||
"ID",
|
||||
"Description",
|
||||
nw = nw,
|
||||
idw = idw,
|
||||
dw = dw,
|
||||
));
|
||||
m.push_line(format!(
|
||||
"{:->nw$}---{:->idw$}---{:->dw$}",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
nw = nw,
|
||||
idw = idw,
|
||||
dw = dw,
|
||||
));
|
||||
}
|
||||
m.push_line("```");
|
||||
m.push(format!("Page **{}/{}**", page + 1, pages));
|
||||
|
||||
msg.edit(ctx, |f| f.content(m.to_string())).await?;
|
||||
Ok(true)
|
||||
for (role, description) in roles.iter() {
|
||||
m.push_line(format!(
|
||||
"{:nw$} | {:idw$} | {:dw$}",
|
||||
role.name,
|
||||
role.id,
|
||||
description,
|
||||
nw = nw,
|
||||
idw = idw,
|
||||
dw = dw,
|
||||
));
|
||||
}
|
||||
m.push_line("```");
|
||||
m.push(format!("Page **{}/{}**", page + 1, pages));
|
||||
|
||||
msg.edit(ctx, |f| f.content(m.to_string())).await?;
|
||||
Ok(true)
|
||||
})
|
||||
},
|
||||
ctx,
|
||||
m.channel_id,
|
||||
|
@ -155,6 +158,7 @@ async fn toggle(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
#[only_in(guilds)]
|
||||
async fn add(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
||||
let role = args.single_quoted::<String>()?;
|
||||
let data = ctx.data.read().await;
|
||||
let description = args.single::<String>()?;
|
||||
let guild_id = m.guild_id.unwrap();
|
||||
let roles = guild_id.to_partial_guild(&ctx).await?.roles;
|
||||
|
@ -164,7 +168,7 @@ async fn add(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
m.reply(&ctx, "No such role exists").await?;
|
||||
}
|
||||
Some(role)
|
||||
if DB::open(&*ctx.data.read().await)
|
||||
if DB::open(&*data)
|
||||
.borrow()?
|
||||
.get(&guild_id)
|
||||
.map(|g| g.contains_key(&role.id))
|
||||
|
@ -174,7 +178,7 @@ async fn add(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
.await?;
|
||||
}
|
||||
Some(role) => {
|
||||
DB::open(&*ctx.data.read().await)
|
||||
DB::open(&*data)
|
||||
.borrow_mut()?
|
||||
.entry(guild_id)
|
||||
.or_default()
|
||||
|
@ -200,6 +204,7 @@ async fn add(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
#[only_in(guilds)]
|
||||
async fn remove(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
||||
let role = args.single_quoted::<String>()?;
|
||||
let data = ctx.data.read().await;
|
||||
let guild_id = m.guild_id.unwrap();
|
||||
let roles = guild_id.to_partial_guild(&ctx).await?.roles;
|
||||
let role = role_from_string(&role, &roles);
|
||||
|
@ -208,7 +213,7 @@ async fn remove(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
m.reply(&ctx, "No such role exists").await?;
|
||||
}
|
||||
Some(role)
|
||||
if !DB::open(&*ctx.data.read().await)
|
||||
if !DB::open(&*data)
|
||||
.borrow()?
|
||||
.get(&guild_id)
|
||||
.map(|g| g.contains_key(&role.id))
|
||||
|
@ -218,7 +223,7 @@ async fn remove(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
|||
.await?;
|
||||
}
|
||||
Some(role) => {
|
||||
DB::open(&*ctx.data.read().await)
|
||||
DB::open(&*data)
|
||||
.borrow_mut()?
|
||||
.entry(guild_id)
|
||||
.or_default()
|
||||
|
|
|
@ -28,7 +28,7 @@ pub async fn vote(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
|||
let args = args.quoted();
|
||||
let _duration = args.single::<ParseDuration>()?;
|
||||
let duration = &_duration.0;
|
||||
if *duration < Duration::from_secs(2 * 60) || *duration > Duration::from_secs(60 * 60 * 24) {
|
||||
if *duration < Duration::from_secs(2) || *duration > Duration::from_secs(60 * 60 * 24) {
|
||||
msg.reply(ctx, format!("😒 Invalid duration ({}). The voting time should be between **2 minutes** and **1 day**.", _duration)).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -97,6 +97,8 @@ pub async fn vote(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
|||
})
|
||||
}).await?;
|
||||
msg.delete(&ctx).await?;
|
||||
drop(msg);
|
||||
|
||||
// React on all the choices
|
||||
choices
|
||||
.iter()
|
||||
|
@ -110,16 +112,18 @@ pub async fn vote(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
|||
.await?;
|
||||
|
||||
// A handler for votes.
|
||||
let mut user_reactions: Map<String, Set<UserId>> = choices
|
||||
let user_reactions: Map<String, Set<UserId>> = choices
|
||||
.iter()
|
||||
.map(|(emote, _)| (emote.clone(), Set::new()))
|
||||
.collect();
|
||||
|
||||
// Collect reactions...
|
||||
msg.await_reactions(&ctx)
|
||||
let user_reactions = panel
|
||||
.await_reactions(&ctx)
|
||||
.removed(true)
|
||||
.timeout(*duration)
|
||||
.await
|
||||
.scan(user_reactions, |set, reaction| async move {
|
||||
.fold(user_reactions, |mut set, reaction| async move {
|
||||
let (reaction, is_add) = match &*reaction {
|
||||
ReactionAction::Added(r) => (r, true),
|
||||
ReactionAction::Removed(r) => (r, false),
|
||||
|
@ -128,23 +132,22 @@ pub async fn vote(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult
|
|||
if let Some(users) = set.get_mut(s.as_str()) {
|
||||
users
|
||||
} else {
|
||||
return None;
|
||||
return set;
|
||||
}
|
||||
} else {
|
||||
return None;
|
||||
return set;
|
||||
};
|
||||
let user_id = match reaction.user_id {
|
||||
Some(v) => v,
|
||||
None => return None,
|
||||
None => return set,
|
||||
};
|
||||
if is_add {
|
||||
users.insert(user_id);
|
||||
} else {
|
||||
users.remove(&user_id);
|
||||
}
|
||||
Some(())
|
||||
set
|
||||
})
|
||||
.collect::<()>()
|
||||
.await;
|
||||
|
||||
// Handle choices
|
||||
|
@ -233,3 +236,4 @@ const REACTIONS: [&'static str; 90] = [
|
|||
|
||||
// Assertions
|
||||
static_assertions::const_assert!(MAX_CHOICES <= REACTIONS.len());
|
||||
static_assertions::const_assert!(MAX_CHOICES <= REACTIONS.len());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue