Add ban command
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use scylla::client::session::Session;
|
||||
|
||||
@@ -10,6 +13,7 @@ use crate::{
|
||||
context::CommandContext,
|
||||
},
|
||||
state::State,
|
||||
utils::split_at_nth_from_end,
|
||||
};
|
||||
|
||||
/// Fetch a user by their ID from the database.
|
||||
@@ -81,12 +85,13 @@ impl FromArguments<State, Extras> for UserArgument {
|
||||
args: &'a str,
|
||||
ctx: &'a CommandContext<'_, State, Extras>,
|
||||
) -> Result<(Self, &'a str), ArgumentParsingError> {
|
||||
let user: User;
|
||||
|
||||
if !args.is_empty() {
|
||||
// There's an argument, so that argument is used to find the user.
|
||||
|
||||
let user: User;
|
||||
|
||||
let (identifier, args) = NeedyString::from_args(args, ctx).await?;
|
||||
let identifier = identifier.0.trim();
|
||||
|
||||
if identifier.starts_with("<@") && identifier.ends_with(">") {
|
||||
// The argument is a Discord mention.
|
||||
@@ -108,7 +113,9 @@ impl FromArguments<State, Extras> for UserArgument {
|
||||
} else {
|
||||
// The argument is (probably) a username.
|
||||
|
||||
let Some(db_user) = User::get_by_name(identifier.0, &ctx.rt.state.db).await? else {
|
||||
let Some(db_user) =
|
||||
User::get_by_name(identifier.to_string(), &ctx.rt.state.db).await?
|
||||
else {
|
||||
// Check in the message's reply, and if not use the command executor.
|
||||
user = user_from_reply_or_command_executor(ctx).await?;
|
||||
|
||||
@@ -117,12 +124,16 @@ impl FromArguments<State, Extras> for UserArgument {
|
||||
|
||||
user = db_user;
|
||||
}
|
||||
|
||||
// Notice that `args` is shadowed above, so this line can't be removed (or else the
|
||||
// full args will be passed and not just the remaining ones as it should be).
|
||||
Ok((UserArgument(user), args))
|
||||
} else {
|
||||
// Check in the message's reply, and if not use the command executor.
|
||||
user = user_from_reply_or_command_executor(ctx).await?;
|
||||
}
|
||||
let user = user_from_reply_or_command_executor(ctx).await?;
|
||||
|
||||
Ok((UserArgument(user), args))
|
||||
Ok((UserArgument(user), args))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,3 +150,47 @@ impl DerefMut for UserArgument {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DurationArgument(pub Duration);
|
||||
|
||||
impl FromArguments<State, Extras> for DurationArgument {
|
||||
async fn from_args<'a>(
|
||||
mut args: &'a str,
|
||||
_ctx: &'a CommandContext<'_, State, Extras>,
|
||||
) -> Result<(Self, &'a str), ArgumentParsingError> {
|
||||
let mut i = 1;
|
||||
let mut finding = None;
|
||||
|
||||
while let Some((substring, remaining_args)) = split_at_nth_from_end(args, " ", i) {
|
||||
if let Ok(duration) = humantime::parse_duration(substring) {
|
||||
finding = Some(DurationArgument(duration));
|
||||
args = remaining_args;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if let Some(duration) = finding {
|
||||
Ok((duration, args))
|
||||
} else {
|
||||
Err(ArgumentParsingError::InvalidArgument)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for DurationArgument {
|
||||
type Target = Duration;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for DurationArgument {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user