1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! Slash command parsing and creation.
//!
//! # Slash commands
//! This crate provide parsing slash command data ([`CommandData`]) as typed structs. It
//! also provide a convenient way to register commands from these structs. Derive macros
//! are provided to automatically implement related traits.
//!
//! ## Command data parsing
//! Parsing is done with the [`CommandModel`] trait which expose the [`from_interaction`]
//! method to parse a [`CommandData`] into a concrete type. A derive macro is available to
//! automatically implement this trait when all field types implements the [`CommandOption`]
//! trait (see below for provided implementations).
//!
//! ### Example usage
//! The following struct correspond to a command that take a required `message` string
//! option and an optional `user` option. The [`ResolvedUser`] type is used to get the
//! optional [`InteractionMember`] associated with the user.
//!
//! ```
//! use twilight_interactions::command::{CommandModel, ResolvedUser};
//!
//! #[derive(CommandModel)]
//! struct HelloCommand {
//!     message: String,
//!     user: Option<ResolvedUser>,
//! }
//! ```
//!
//! This type can then be initialized from a [`CommandData`] using the [`from_interaction`] method.
//!
//! ### Command options validation
//! The [`CommandModel`] only focus on parsing received command data and does not
//! provide a way to perform additional validation. We only support field types
//! that can be validated by Discord.
//!
//! For example, you can use [`User`] in models but not directly [`InteractionMember`] because
//! there is no guarantee that member data will be present when received a `USER` option.
//! The [`ResolvedUser`] type can instead be used to get an optional member object.
//!
//! Because of that, all errors that might occurs when parsing are caused either by invalid
//! data sent by Discord or invalid command registration. It cannot be a bad user input.
//! If you perform additional validation, consider create another type that can be initialized
//! from the raw parsed data.
//!
//! ## Command creation
//! In addition to command data parsing, the [`CreateCommand`] trait and derive macro are
//! provided to register commands corresponding to your models to the Discord API. This
//! is provided by a separate trait because this trait has more advanced requirements
//! that for parsing.
//!
//! The trait can be automatically implemented on struct where all field types implements
//! [`CreateOption`] and have a description (see the example below). The command name must
//! also be provided with the `command` attribute.
//!
//! The derive macro provide a `#[command]` attribute to provide additional information
//! about the command. Refer to the [`CreateCommand`] trait documentation for a full
//! reference of available options.
//!
//! ### Example usage
//! This example is the same as the previous, but additional information has been provided
//! about the command. The same type can derive both [`CommandModel`] and [`CreateCommand`].
//!
//! The example shows two ways to provide a description to the command and its field:
//! - Using documentation comments. Only the first line is used, other are ignored.
//! - Using the `desc` parameter of the `#[command]` attribute.
//!
//! If both are provided, the `desc` parameter will be used.
//!
//! ```
//! use twilight_interactions::command::{CreateCommand, ResolvedUser};
//!
//! #[derive(CreateCommand)]
//! #[command(name = "hello", desc = "Say hello")]
//! struct HelloCommand {
//!     /// The message to send.
//!     message: String,
//!     /// The user to send the message to.
//!     user: Option<ResolvedUser>,
//! }
//! ```
//!
//! An [`ApplicationCommandData`] type corresponding to the command can be obtained using the
//! [`create_command`] method.
//!
//! ## Supported types
//! The [`CommandOption`] and [`CreateOption`] traits are implemented for the following types:
//!
//! | Command option type | Provided implementations               |
//! |---------------------|----------------------------------------|
//! | `STRING`            | [`String`]                             |
//! | `INTEGER`           | [`i64`]                                |
//! | `NUMBER`            | [`Number`], [`f64`]
//! | `BOOLEAN`           | [`bool`]                               |
//! | `USER`              | [`ResolvedUser`], [`User`], [`UserId`] |
//! | `CHANNEL`           | [`InteractionChannel`], [`ChannelId`]  |
//! | `ROLE`              | [`Role`], [`RoleId`]                   |
//! | `MENTIONABLE`       | [`GenericId`]                          |
//! | `SUB_COMMAND`       | Not yet implemented.                   |
//! | `SUB_COMMAND_GROUP` | Not yet implemented.                   |
//!
//! [`from_interaction`]: CommandModel::from_interaction
//! [`create_command`]: CreateCommand::create_command
//!
//! [`CommandData`]: twilight_model::application::interaction::application_command::CommandData
//! [`InteractionMember`]: twilight_model::application::interaction::application_command::InteractionMember
//!
//! [`Number`]: twilight_model::application::command::Number
//! [`User`]: twilight_model::user::User
//! [`UserId`]: twilight_model::id::UserId
//! [`InteractionChannel`]: twilight_model::application::interaction::application_command::InteractionChannel
//! [`ChannelId`]: twilight_model::id::ChannelId
//! [`Role`]: twilight_model::guild::Role
//! [`RoleId`]: twilight_model::id::RoleId
//! [`GenericId`]: twilight_model::id::GenericId

mod command_model;
mod create_command;

pub use command_model::{CommandModel, CommandOption, ResolvedUser};
pub use create_command::{ApplicationCommandData, CommandOptionData, CreateCommand, CreateOption};

#[cfg(feature = "derive")]
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub use twilight_interactions_derive::{CommandModel, CreateCommand};