Skip to content

Commit

Permalink
Adds "unstable-exhaustive-types" as new feature.
Browse files Browse the repository at this point in the history
This feature deactivates all "#[non_exhaustive]" added into the code. This can be used by developers to ensure, that they match all enum variants or struct fields during pattern matching.
  • Loading branch information
TheCataliasTNT2k committed Nov 24, 2024
1 parent 22b5b01 commit 5b1d6c0
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 22 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ collector = []
# build time for peace of mind.
handle_panics = []

# Disables all "#[non_exhaustive), non_exhaustive)]" macros to ensure, that all enum variants or struct fields are required when pattern matching.
unstable_exhaustive_types = []

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ["cfg(doc_nightly)"] }

Expand Down
2 changes: 1 addition & 1 deletion src/cooldown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub struct CooldownTracker {
/// Possible types of command cooldowns.
///
/// Currently used for [CooldownTracker::set_last_invocation]
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
pub enum CooldownType {
/// A global cooldown that applies to all users, channels, and guilds.
Global,
Expand Down
6 changes: 3 additions & 3 deletions src/slash_argument/slash_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ pub enum SlashArgError {
///
/// Most often the result of the bot not having registered the command in Discord, so Discord
/// stores an outdated version of the command and its parameters.
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
CommandStructureMismatch {
/// A short string describing what specifically is wrong/unexpected
description: &'static str,
},
/// A string parameter was found, but it could not be parsed into the target type.
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
Parse {
/// Error that occurred while parsing the string into the target type
error: Box<dyn std::error::Error + Send + Sync>,
/// Original input string
input: String,
},
/// The argument passed by the user is invalid in this context. E.g. a Member parameter in DMs
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
Invalid(
/// Human readable description of the error
&'static str,
Expand Down
37 changes: 19 additions & 18 deletions src/structs/framework_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::serenity_prelude as serenity;
#[derivative(Debug)]
pub enum FrameworkError<'a, U, E> {
/// User code threw an error in user data setup
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
Setup {
/// Error which was thrown in the setup code
error: E,
Expand All @@ -24,7 +24,7 @@ pub enum FrameworkError<'a, U, E> {
ctx: &'a serenity::Context,
},
/// User code threw an error in generic event event handler
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
EventHandler {
/// Error which was thrown in the event handler code
error: E,
Expand All @@ -37,7 +37,7 @@ pub enum FrameworkError<'a, U, E> {
framework: crate::FrameworkContext<'a, U, E>,
},
/// Error occurred during command execution
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
Command {
/// Error which was thrown in the command code
error: E,
Expand All @@ -54,7 +54,7 @@ pub enum FrameworkError<'a, U, E> {
/// This feature is intended as a last-resort safeguard to gracefully print an error message to
/// the user on a panic. Panics should only be thrown for bugs in the code, don't use this for
/// normal errors!
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
CommandPanic {
/// Panic payload which was thrown in the command code
///
Expand All @@ -68,7 +68,7 @@ pub enum FrameworkError<'a, U, E> {
ctx: crate::Context<'a, U, E>,
},
/// A command argument failed to parse from the Discord message or interaction content
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
ArgumentParse {
/// Error which was thrown by the parameter type's parsing routine
error: Box<dyn std::error::Error + Send + Sync>,
Expand All @@ -82,15 +82,15 @@ pub enum FrameworkError<'a, U, E> {
///
/// Most often the result of the bot not having registered the command in Discord, so Discord
/// stores an outdated version of the command and its parameters.
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
CommandStructureMismatch {
/// Developer-readable description of the type mismatch
description: &'static str,
/// General context
ctx: crate::ApplicationContext<'a, U, E>,
},
/// Command was invoked before its cooldown expired
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
CooldownHit {
/// Time until the command may be invoked for the next time in the given context
remaining_cooldown: std::time::Duration,
Expand All @@ -99,7 +99,7 @@ pub enum FrameworkError<'a, U, E> {
},
/// Command was invoked but the bot is lacking the permissions specified in
/// [`crate::Command::required_bot_permissions`]
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
MissingBotPermissions {
/// Which permissions in particular the bot is lacking for this command
missing_permissions: serenity::Permissions,
Expand All @@ -108,7 +108,7 @@ pub enum FrameworkError<'a, U, E> {
},
/// Command was invoked but the user is lacking the permissions specified in
/// [`crate::Command::required_permissions`]
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
MissingUserPermissions {
/// List of permissions that the user is lacking. May be None if retrieving the user's
/// permissions failed
Expand All @@ -117,31 +117,31 @@ pub enum FrameworkError<'a, U, E> {
ctx: crate::Context<'a, U, E>,
},
/// A non-owner tried to invoke an owners-only command
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
NotAnOwner {
/// General context
ctx: crate::Context<'a, U, E>,
},
/// Command was invoked but the channel was a DM channel
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
GuildOnly {
/// General context
ctx: crate::Context<'a, U, E>,
},
/// Command was invoked but the channel was a non-DM channel
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
DmOnly {
/// General context
ctx: crate::Context<'a, U, E>,
},
/// Command was invoked but the channel wasn't a NSFW channel
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
NsfwOnly {
/// General context
ctx: crate::Context<'a, U, E>,
},
/// Provided pre-command check either errored, or returned false, so command execution aborted
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
CommandCheckFailed {
/// If execution wasn't aborted because of an error but because it successfully returned
/// false, this field is None
Expand All @@ -151,7 +151,7 @@ pub enum FrameworkError<'a, U, E> {
},
/// [`crate::PrefixFrameworkOptions::dynamic_prefix`] or
/// [`crate::PrefixFrameworkOptions::stripped_dynamic_prefix`] returned an error
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
DynamicPrefix {
/// Error which was thrown in the dynamic prefix code
error: E,
Expand All @@ -162,7 +162,7 @@ pub enum FrameworkError<'a, U, E> {
msg: &'a serenity::Message,
},
/// A message had the correct prefix but the following string was not a recognized command
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
UnknownCommand {
/// Serenity's Context
#[derivative(Debug = "ignore")]
Expand All @@ -185,7 +185,7 @@ pub enum FrameworkError<'a, U, E> {
trigger: crate::MessageDispatchTrigger,
},
/// The command name from the interaction is unrecognized
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
UnknownInteraction {
#[derivative(Debug = "ignore")]
/// Serenity's Context
Expand All @@ -197,7 +197,7 @@ pub enum FrameworkError<'a, U, E> {
interaction: &'a serenity::CommandInteraction,
},
/// An error occurred in [`crate::PrefixFrameworkOptions::non_command_message`]
#[non_exhaustive]
#[cfg_attr(any(not(feature = "unstable_exhaustive_types"), doc), non_exhaustive)]
NonCommandMessage {
/// The error thrown by user code
error: E,
Expand All @@ -211,6 +211,7 @@ pub enum FrameworkError<'a, U, E> {
msg: &'a serenity::Message,
},
// #[non_exhaustive] forbids struct update syntax for ?? reason
#[cfg(any(not(feature = "unstable_exhaustive_types"), doc))]
#[doc(hidden)]
__NonExhaustive(std::convert::Infallible),
}
Expand Down
1 change: 1 addition & 0 deletions src/structs/framework_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub struct FrameworkOptions<U, E> {
/// None by default.
pub initialized_team_roles: Option<Vec<serenity::TeamMemberRole>>,
// #[non_exhaustive] forbids struct update syntax for ?? reason
#[cfg(any(not(feature = "unstable_exhaustive_types"), doc))]
#[doc(hidden)]
pub __non_exhaustive: (),
}
Expand Down
2 changes: 2 additions & 0 deletions src/structs/prefix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub struct PrefixContext<'a, U, E> {
) -> crate::BoxFuture<'_, Result<(), crate::FrameworkError<'_, U, E>>>,

// #[non_exhaustive] forbids struct update syntax for ?? reason
#[cfg(any(not(feature = "unstable_exhaustive_types"), doc))]
#[doc(hidden)]
pub __non_exhaustive: (),
}
Expand Down Expand Up @@ -171,6 +172,7 @@ pub struct PrefixFrameworkOptions<U, E> {
// /// single parameter
// pub command_specific_help_commmand: Option<Command<U, E>>, */
// #[non_exhaustive] forbids struct update syntax for ?? reason
#[cfg(any(not(feature = "unstable_exhaustive_types"), doc))]
#[doc(hidden)]
pub __non_exhaustive: (),
}
Expand Down
1 change: 1 addition & 0 deletions src/structs/slash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub struct ApplicationContext<'a, U, E> {
/// Custom user data carried across a single command invocation
pub invocation_data: &'a tokio::sync::Mutex<Box<dyn std::any::Any + Send + Sync>>,
// #[non_exhaustive] forbids struct update syntax for ?? reason
#[cfg(any(not(feature = "unstable_exhaustive_types"), doc))]
#[doc(hidden)]
pub __non_exhaustive: (),
}
Expand Down

0 comments on commit 5b1d6c0

Please sign in to comment.