use std::{
collections::HashSet,
fmt,
};
use crate::client::Context;
use crate::model::{
channel::Message,
permissions::Permissions,
id::UserId,
};
use crate::utils::Colour;
use super::Args;
mod check;
pub mod buckets;
pub use self::check::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OnlyIn {
Dm,
Guild,
None,
#[doc(hidden)]
__Nonexhaustive,
}
#[derive(Debug, PartialEq)]
pub struct CommandOptions {
pub checks: &'static [&'static Check],
pub bucket: Option<&'static str>,
pub names: &'static [&'static str],
pub desc: Option<&'static str>,
pub usage: Option<&'static str>,
pub example: Option<&'static str>,
pub min_args: Option<u16>,
pub max_args: Option<u16>,
pub allowed_roles: &'static [&'static str],
pub required_permissions: Permissions,
pub help_available: bool,
pub only_in: OnlyIn,
pub owners_only: bool,
pub owner_privilege: bool,
pub sub_commands: &'static [&'static Command],
}
#[derive(Debug, PartialEq)]
pub struct GroupOptions {
pub prefixes: &'static [&'static str],
pub only_in: OnlyIn,
pub owners_only: bool,
pub owner_privilege: bool,
pub help_available: bool,
pub allowed_roles: &'static [&'static str],
pub required_permissions: Permissions,
pub checks: &'static [&'static Check],
pub default_command: Option<&'static Command>,
pub description: Option<&'static str>,
}
#[derive(Debug, Clone)]
pub struct CommandError(pub String);
impl<T: fmt::Display> From<T> for CommandError {
#[inline]
fn from(d: T) -> Self {
CommandError(d.to_string())
}
}
pub type CommandResult = ::std::result::Result<(), CommandError>;
pub type CommandFn = fn(&mut Context, &Message, Args) -> CommandResult;
pub struct Command {
pub fun: CommandFn,
pub options: &'static CommandOptions,
}
impl fmt::Debug for Command {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Command")
.field("options", &self.options)
.finish()
}
}
impl PartialEq for Command {
#[inline]
fn eq(&self, other: &Command) -> bool {
(self.fun as usize == other.fun as usize) && (self.options == other.options)
}
}
pub type HelpCommandFn = fn(
&mut Context,
&Message,
Args,
&'static HelpOptions,
&[&'static CommandGroup],
HashSet<UserId>,
) -> CommandResult;
pub struct HelpCommand {
pub fun: HelpCommandFn,
pub options: &'static HelpOptions,
}
impl fmt::Debug for HelpCommand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("HelpCommand")
.field("fun", &"<function>")
.field("options", &self.options)
.finish()
}
}
impl PartialEq for HelpCommand {
#[inline]
fn eq(&self, other: &HelpCommand) -> bool {
(self.fun as usize == other.fun as usize) && (self.options == other.options)
}
}
#[derive(Copy, Clone, Debug, PartialOrd, Ord, Eq, PartialEq)]
pub enum HelpBehaviour {
Nothing,
Strike,
Hide,
#[doc(hidden)]
__Nonexhaustive,
}
#[derive(Clone, Debug, PartialEq)]
pub struct HelpOptions {
pub names: &'static [&'static str],
pub suggestion_text: &'static str,
pub no_help_available_text: &'static str,
pub usage_label: &'static str,
pub usage_sample_label: &'static str,
pub ungrouped_label: &'static str,
pub description_label: &'static str,
pub grouped_label: &'static str,
pub aliases_label: &'static str,
pub guild_only_text: &'static str,
pub checks_label: &'static str,
pub dm_only_text: &'static str,
pub dm_and_guild_text: &'static str,
pub available_text: &'static str,
pub command_not_found_text: &'static str,
pub individual_command_tip: &'static str,
pub strikethrough_commands_tip_in_dm: Option<&'static str>,
pub strikethrough_commands_tip_in_guild: Option<&'static str>,
pub group_prefix: &'static str,
pub lacking_role: HelpBehaviour,
pub lacking_permissions: HelpBehaviour,
pub lacking_ownership: HelpBehaviour,
pub wrong_channel: HelpBehaviour,
pub embed_error_colour: Colour,
pub embed_success_colour: Colour,
pub max_levenshtein_distance: usize,
pub indention_prefix: &'static str,
}
#[derive(Debug, PartialEq)]
pub struct CommandGroup {
pub help_name: &'static str,
pub name: &'static str,
pub options: &'static GroupOptions,
pub commands: &'static [&'static Command],
pub sub_groups: &'static [&'static CommandGroup],
}
#[cfg(test)]
#[cfg(all(feature = "cache", feature = "http"))]
mod levenshtein_tests {
use super::HelpBehaviour;
#[test]
fn help_behaviour_eq() {
assert_eq!(HelpBehaviour::Hide, std::cmp::max(HelpBehaviour::Hide, HelpBehaviour::Hide));
assert_eq!(HelpBehaviour::Strike, std::cmp::max(HelpBehaviour::Strike, HelpBehaviour::Strike));
assert_eq!(HelpBehaviour::Nothing, std::cmp::max(HelpBehaviour::Nothing, HelpBehaviour::Nothing));
}
#[test]
fn help_behaviour_hide() {
assert_eq!(HelpBehaviour::Hide, std::cmp::max(HelpBehaviour::Hide, HelpBehaviour::Nothing));
assert_eq!(HelpBehaviour::Hide, std::cmp::max(HelpBehaviour::Hide, HelpBehaviour::Strike));
}
#[test]
fn help_behaviour_strike() {
assert_eq!(HelpBehaviour::Strike, std::cmp::max(HelpBehaviour::Strike, HelpBehaviour::Nothing));
assert_eq!(HelpBehaviour::Hide, std::cmp::max(HelpBehaviour::Strike, HelpBehaviour::Hide));
}
#[test]
fn help_behaviour_nothing() {
assert_eq!(HelpBehaviour::Strike, std::cmp::max(HelpBehaviour::Nothing, HelpBehaviour::Strike));
assert_eq!(HelpBehaviour::Hide, std::cmp::max(HelpBehaviour::Nothing, HelpBehaviour::Hide));
}
}