Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(validate, http)!: validate command and options names #1395

Merged
merged 9 commits into from
Jan 11, 2022
35 changes: 5 additions & 30 deletions http/src/client/interaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,11 @@ impl<'a> InteractionClient<'a> {
}

/// Create a new command in a guild.
///
/// The name must be between 1 and 32 characters in length. Creating a
/// guild command with the same name as an already-existing guild command in
/// the same guild will overwrite the old command. See [the discord docs]
/// for more information.
///
/// Returns an error of type [`NameInvalid`] error type if the command name
/// is not between 1 and 32 characters.
///
/// [`NameInvalid`]: twilight_validate::command::CommandValidationErrorType::NameInvalid
/// [the discord docs]: https://discord.com/developers/docs/interactions/application-commands#create-guild-application-command
pub fn create_guild_command(
pub const fn create_guild_command(
&'a self,
guild_id: Id<GuildMarker>,
name: &'a str,
) -> Result<CreateGuildCommand<'a>, CommandValidationError> {
CreateGuildCommand::new(self.client, self.application_id, guild_id, name)
) -> CreateGuildCommand<'a> {
CreateGuildCommand::new(self.client, self.application_id, guild_id)
}

/// Fetch a guild command for your application.
Expand Down Expand Up @@ -236,21 +224,8 @@ impl<'a> InteractionClient<'a> {
}

/// Create a new global command.
///
/// The name must be between 1 and 32 characters in length. Creating a
/// command with the same name as an already-existing global command will
/// overwrite the old command. See [the discord docs] for more information.
///
/// Returns an error of type [`NameInvalid`] if the command name is not
/// between 1 and 32 characters.
///
/// [`NameInvalid`]: twilight_validate::command::CommandValidationErrorType::NameInvalid
/// [the discord docs]: https://discord.com/developers/docs/interactions/application-commands#create-global-application-command
pub fn create_global_command(
&'a self,
name: &'a str,
) -> Result<CreateGlobalCommand<'a>, CommandValidationError> {
CreateGlobalCommand::new(self.client, self.application_id, name)
pub const fn create_global_command(&'a self) -> CreateGlobalCommand<'a> {
CreateGlobalCommand::new(self.client, self.application_id)
}

/// Fetch a global command for your application.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use twilight_model::{
id::{marker::ApplicationMarker, Id},
};
use twilight_validate::command::{
description as validate_description, options as validate_options, CommandValidationError,
chat_input_name as validate_chat_input_name, description as validate_description,
options as validate_options, CommandValidationError,
};

/// Create a new chat input global command.
Expand Down Expand Up @@ -40,6 +41,8 @@ impl<'a> CreateGlobalChatInputCommand<'a> {
) -> Result<Self, CommandValidationError> {
validate_description(&description)?;

validate_chat_input_name(name)?;

Ok(Self {
application_id,
default_permission: None,
Expand All @@ -54,7 +57,7 @@ impl<'a> CreateGlobalChatInputCommand<'a> {
///
/// Required command options must be added before optional options.
///
/// Errors
/// # Errors
///
/// Returns an error of type [`OptionsRequiredFirst`] if a required option
/// was added after an optional option. The problem option's index is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use twilight_model::{
application::command::{Command, CommandType},
id::{marker::ApplicationMarker, Id},
};
use twilight_validate::command::{name as validate_name, CommandValidationError};

/// Create a new message global command.
///
Expand All @@ -26,17 +27,19 @@ pub struct CreateGlobalMessageCommand<'a> {
}

impl<'a> CreateGlobalMessageCommand<'a> {
pub(crate) const fn new(
pub(crate) fn new(
http: &'a Client,
application_id: Id<ApplicationMarker>,
name: &'a str,
) -> Self {
Self {
) -> Result<Self, CommandValidationError> {
validate_name(name)?;

Ok(Self {
application_id,
default_permission: None,
http,
name,
}
})
}

/// Whether the command is enabled by default when the app is added to a guild.
Expand Down
68 changes: 41 additions & 27 deletions http/src/request/application/command/create_global_command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,51 @@ pub use self::{

use crate::Client;
use twilight_model::id::{marker::ApplicationMarker, Id};
use twilight_validate::command::{name as validate_name, CommandValidationError};
use twilight_validate::command::CommandValidationError;

/// Create a new global command.
///
/// The name must be between 1 and 32 characters in length. Creating a command
/// with the same name as an already-existing global command will overwrite the
/// old command. See [the discord docs] for more information.
///
/// [the discord docs]: https://discord.com/developers/docs/interactions/application-commands#create-global-application-command
#[must_use = "the command must have a type"]
pub struct CreateGlobalCommand<'a> {
application_id: Id<ApplicationMarker>,
http: &'a Client,
name: &'a str,
}

impl<'a> CreateGlobalCommand<'a> {
pub(crate) fn new(
http: &'a Client,
application_id: Id<ApplicationMarker>,
name: &'a str,
) -> Result<Self, CommandValidationError> {
validate_name(name)?;

Ok(Self {
pub(crate) const fn new(http: &'a Client, application_id: Id<ApplicationMarker>) -> Self {
Self {
application_id,
http,
name,
})
}
}

/// Create a new chat input global command.
///
/// The description must be between 1 and 100 characters in length. Creating
/// a command with the same name as an already-existing global command will
/// overwrite the old command. See [the discord docs] for more information.
/// The command name must only contain alphanumeric characters and lowercase
/// variants must be used where possible. Special characters `-` and `_` are
/// allowed. The description must be between 1 and 100 characters in length.
///
/// Creating a command with the same name as an already-existing global
/// command will overwrite the old command. See [the discord docs] for more
/// information.
///
/// # Errors
///
/// Returns an error of type [`DescriptionInvalid`] error type if the
/// Returns an error of type [`NameLengthInvalid`] or [`NameCharacterInvalid`]
/// if the command name is invalid.
///
/// Returns an error of type [`DescriptionInvalid`] if the
/// command description is not between 1 and 100 characters.
///
/// [`NameLengthInvalid`]: twilight_validate::command::CommandValidationErrorType::NameLengthInvalid
/// [`NameCharacterInvalid`]: twilight_validate::command::CommandValidationErrorType::NameCharacterInvalid
/// [`DescriptionInvalid`]: twilight_validate::command::CommandValidationErrorType::DescriptionInvalid
/// [the discord docs]: https://discord.com/developers/docs/interactions/application-commands#create-global-application-command
pub fn chat_input(
self,
name: &'a str,
description: &'a str,
) -> Result<CreateGlobalChatInputCommand<'a>, CommandValidationError> {
CreateGlobalChatInputCommand::new(self.http, self.application_id, self.name, description)
CreateGlobalChatInputCommand::new(self.http, self.application_id, name, description)
}

/// Create a new message global command.
Expand All @@ -66,9 +62,18 @@ impl<'a> CreateGlobalCommand<'a> {
/// command will overwrite the old command. See [the discord docs] for more
/// information.
///
/// # Errors
///
/// Returns an error of type [`NameLengthInvalid`] if the command name is
/// not between 1 and 32 characters.
///
/// [`NameLengthInvalid`]: twilight_validate::command::CommandValidationErrorType::NameLengthInvalid
/// [the discord docs]: https://discord.com/developers/docs/interactions/application-commands#create-global-application-command
pub const fn message(self) -> CreateGlobalMessageCommand<'a> {
CreateGlobalMessageCommand::new(self.http, self.application_id, self.name)
pub fn message(
self,
name: &'a str,
) -> Result<CreateGlobalMessageCommand<'a>, CommandValidationError> {
CreateGlobalMessageCommand::new(self.http, self.application_id, name)
}

/// Create a new user global command.
Expand All @@ -77,8 +82,17 @@ impl<'a> CreateGlobalCommand<'a> {
/// command will overwrite the old command. See [the discord docs] for more
/// information.
///
/// # Errors
///
/// Returns an error of type [`NameLengthInvalid`] if the command name is
/// not between 1 and 32 characters.
///
/// [`NameLengthInvalid`]: twilight_validate::command::CommandValidationErrorType::NameLengthInvalid
/// [the discord docs]: https://discord.com/developers/docs/interactions/application-commands#create-global-application-command
pub const fn user(self) -> CreateGlobalUserCommand<'a> {
CreateGlobalUserCommand::new(self.http, self.application_id, self.name)
pub fn user(
self,
name: &'a str,
) -> Result<CreateGlobalUserCommand<'a>, CommandValidationError> {
CreateGlobalUserCommand::new(self.http, self.application_id, name)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use twilight_model::{
application::command::{Command, CommandType},
id::{marker::ApplicationMarker, Id},
};
use twilight_validate::command::{name as validate_name, CommandValidationError};

/// Create a new user global command.
///
Expand All @@ -26,17 +27,19 @@ pub struct CreateGlobalUserCommand<'a> {
}

impl<'a> CreateGlobalUserCommand<'a> {
pub(crate) const fn new(
pub(crate) fn new(
http: &'a Client,
application_id: Id<ApplicationMarker>,
name: &'a str,
) -> Self {
Self {
) -> Result<Self, CommandValidationError> {
validate_name(name)?;

Ok(Self {
application_id,
default_permission: None,
http,
name,
}
})
}

/// Whether the command is enabled by default when the app is added to a guild.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use twilight_model::{
},
};
use twilight_validate::command::{
description as validate_description, options as validate_options, CommandValidationError,
chat_input_name as validate_chat_input_name, description as validate_description,
options as validate_options, CommandValidationError,
};

/// Create a chat input command in a guild.
Expand Down Expand Up @@ -46,6 +47,8 @@ impl<'a> CreateGuildChatInputCommand<'a> {
) -> Result<Self, CommandValidationError> {
validate_description(&description)?;

validate_chat_input_name(name)?;

Ok(Self {
application_id,
default_permission: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use twilight_model::{
Id,
},
};
use twilight_validate::command::{name as validate_name, CommandValidationError};

/// Create a message command in a guild.
///
Expand All @@ -31,19 +32,21 @@ pub struct CreateGuildMessageCommand<'a> {
}

impl<'a> CreateGuildMessageCommand<'a> {
pub(crate) const fn new(
pub(crate) fn new(
http: &'a Client,
application_id: Id<ApplicationMarker>,
guild_id: Id<GuildMarker>,
name: &'a str,
) -> Self {
Self {
) -> Result<Self, CommandValidationError> {
validate_name(name)?;

Ok(Self {
application_id,
default_permission: None,
guild_id,
http,
name,
}
})
}

/// Whether the command is enabled by default when the app is added to a
Expand Down
Loading