From 36d708cacf7b03723b21f0d74118c4b8dc3da693 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Sun, 24 Jul 2022 20:18:44 -0400 Subject: [PATCH 01/11] Enforce required fields for AddMember --- src/builder/add_member.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/builder/add_member.rs b/src/builder/add_member.rs index 07b796b73ed..4c292e17d1b 100644 --- a/src/builder/add_member.rs +++ b/src/builder/add_member.rs @@ -7,11 +7,10 @@ use crate::model::prelude::*; /// A builder to add parameters when using [`GuildId::add_member`]. /// /// [`GuildId::add_member`]: crate::model::id::GuildId::add_member -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct AddMember { - #[serde(skip_serializing_if = "Option::is_none")] - access_token: Option, + access_token: String, #[serde(skip_serializing_if = "Option::is_none")] nick: Option, #[serde(skip_serializing_if = "Vec::is_empty")] @@ -23,6 +22,17 @@ pub struct AddMember { } impl AddMember { + /// Constructs a new builder with the given access token, leaving all other fields empty. + pub fn new(access_token: String) -> Self { + Self { + access_token, + nick: None, + roles: Vec::new(), + mute: None, + deaf: None, + } + } + /// Adds a [`User`] to this guild with a valid OAuth2 access token. /// /// Returns the created [`Member`] object, or nothing if the user is already a member of the @@ -42,11 +52,11 @@ impl AddMember { http.as_ref().add_guild_member(guild_id.into(), user_id.into(), &self).await } - /// Sets the OAuth2 access token for this request. + /// Sets the OAuth2 access token for this request, replacing the current one. /// /// Requires the access token to have the `guilds.join` scope granted. pub fn access_token(mut self, access_token: impl Into) -> Self { - self.access_token = Some(access_token.into()); + self.access_token = access_token.into(); self } From 39909f1a1be0cf1520b5bc340c89f8e7d16a6420 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Sun, 24 Jul 2022 20:19:16 -0400 Subject: [PATCH 02/11] Enforce required fields for CreateChannel --- src/builder/create_channel.rs | 51 ++++++++++++++------------------ src/model/guild/guild_id.rs | 2 +- src/model/guild/mod.rs | 2 +- src/model/guild/partial_guild.rs | 2 +- 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/builder/create_channel.rs b/src/builder/create_channel.rs index 36673acc3c4..e127867d073 100644 --- a/src/builder/create_channel.rs +++ b/src/builder/create_channel.rs @@ -11,8 +11,7 @@ use crate::model::prelude::*; #[must_use] pub struct CreateChannel { kind: ChannelType, - #[serde(skip_serializing_if = "Option::is_none")] - name: Option, + name: String, #[serde(skip_serializing_if = "Option::is_none")] parent_id: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -31,6 +30,23 @@ pub struct CreateChannel { } impl CreateChannel { + /// Creates a builder with the given name, setting [`Self::kind`] to [`ChannelType::Text`] and + /// leaving all other fields empty. + pub fn new(name: impl Into) -> Self { + Self { + name: name.into(), + nsfw: None, + topic: None, + bitrate: None, + position: None, + parent_id: None, + user_limit: None, + rate_limit_per_user: None, + kind: ChannelType::Text, + permission_overwrites: Vec::new(), + } + } + /// Creates a new [`Channel`] in the guild. /// /// **Note**: Requires the [Manage Channels] permission. @@ -60,11 +76,11 @@ impl CreateChannel { http.create_channel(guild_id.into(), &self, None).await } - /// Specify how to call this new channel. + /// Specify how to call this new channel, replacing the current value as set in [`Self::new`]. /// /// **Note**: Must be between 2 and 100 characters long. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = name.into(); self } @@ -75,7 +91,7 @@ impl CreateChannel { } /// Specify the category, the "parent" of this channel. - pub fn category>(mut self, id: I) -> Self { + pub fn category(mut self, id: impl Into) -> Self { self.parent_id = Some(id.into()); self } @@ -153,34 +169,13 @@ impl CreateChannel { /// kind: PermissionOverwriteType::Member(UserId::new(1234)), /// }]; /// - /// let builder = CreateChannel::default().name("my_new_cool_channel").permissions(permissions); + /// let builder = CreateChannel::new("my_new_cool_channel").permissions(permissions); /// guild.create_channel(&http, builder).await?; /// # Ok(()) /// # } /// ``` - pub fn permissions(mut self, perms: I) -> Self - where - I: IntoIterator, - { + pub fn permissions(mut self, perms: impl IntoIterator) -> Self { self.permission_overwrites = perms.into_iter().map(Into::into).collect(); self } } - -impl Default for CreateChannel { - /// Creates a builder with default values, setting [`Self::kind`] to [`ChannelType::Text`]. - fn default() -> Self { - Self { - name: None, - nsfw: None, - topic: None, - bitrate: None, - position: None, - parent_id: None, - user_limit: None, - rate_limit_per_user: None, - kind: ChannelType::Text, - permission_overwrites: Vec::new(), - } - } -} diff --git a/src/model/guild/guild_id.rs b/src/model/guild/guild_id.rs index e3ea6e811a5..02cbaa57d7f 100644 --- a/src/model/guild/guild_id.rs +++ b/src/model/guild/guild_id.rs @@ -317,7 +317,7 @@ impl GuildId { /// /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); - /// let builder = CreateChannel::default().name("test").kind(ChannelType::Voice); + /// let builder = CreateChannel::new("test").kind(ChannelType::Voice); /// let _channel = GuildId::new(7).create_channel(&http, builder).await?; /// # Ok(()) /// # } diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index 4471d08b795..cf3d87d461e 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -660,7 +660,7 @@ impl Guild { /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); /// # let guild = Guild::get(&http, GuildId::new(7)).await?; - /// let builder = CreateChannel::default().name("my-test-channel").kind(ChannelType::Text); + /// let builder = CreateChannel::new("my-test-channel").kind(ChannelType::Text); /// /// // assuming a `guild` has already been bound /// let _channel = guild.create_channel(&http, builder).await?; diff --git a/src/model/guild/partial_guild.rs b/src/model/guild/partial_guild.rs index 2469474b0fe..412704e3810 100644 --- a/src/model/guild/partial_guild.rs +++ b/src/model/guild/partial_guild.rs @@ -382,7 +382,7 @@ impl PartialGuild { /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); /// # let guild = PartialGuild::get(&http, GuildId::new(7)).await?; - /// let builder = CreateChannel::default().name("my-test-channel").kind(ChannelType::Text); + /// let builder = CreateChannel::new("my-test-channel").kind(ChannelType::Text); /// /// // assuming a `guild` has already been bound /// let _channel = guild.create_channel(&http, builder).await?; From 15dfff3cd66173c9c6e1259dbd0d571038dda61f Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Sun, 24 Jul 2022 22:03:18 -0400 Subject: [PATCH 03/11] Enforce required fields for CreateScheduledEvent --- src/builder/create_scheduled_event.rs | 72 ++++++++++++++------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/builder/create_scheduled_event.rs b/src/builder/create_scheduled_event.rs index 4f6635a3571..4e6a001b28e 100644 --- a/src/builder/create_scheduled_event.rs +++ b/src/builder/create_scheduled_event.rs @@ -9,18 +9,15 @@ use crate::utils::encode_image; #[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateScheduledEvent { + name: String, #[serde(skip_serializing_if = "Option::is_none")] channel_id: Option, #[serde(skip_serializing_if = "Option::is_none")] - name: Option, - #[serde(skip_serializing_if = "Option::is_none")] description: Option, - #[serde(skip_serializing_if = "Option::is_none")] - scheduled_start_time: Option, + scheduled_start_time: String, #[serde(skip_serializing_if = "Option::is_none")] scheduled_end_time: Option, - #[serde(skip_serializing_if = "Option::is_none")] - entity_type: Option, + entity_type: ScheduledEventType, #[serde(skip_serializing_if = "Option::is_none")] entity_metadata: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -30,6 +27,31 @@ pub struct CreateScheduledEvent { } impl CreateScheduledEvent { + /// Creates a builder with the provided kind, name, and start time, leaving all other fields + /// empty. + pub fn new( + kind: ScheduledEventType, + name: impl Into, + scheduled_start_time: impl Into, + ) -> Self { + Self { + name: name.into(), + entity_type: kind, + scheduled_start_time: scheduled_start_time.into().to_string(), + + image: None, + channel_id: None, + description: None, + entity_metadata: None, + scheduled_end_time: None, + + // Set the privacy level to `GUILD_ONLY`. As this is the only possible value of this + // field, it's onlyu used at event creation, and we don't even parse it into the + // `ScheduledEvent` struct. + privacy_level: 2, + } + } + /// Creates a new scheduled event in the guild with the data set, if any. /// /// **Note**: Requires the [Manage Events] permission. @@ -66,9 +88,9 @@ impl CreateScheduledEvent { self } - /// Sets the name of the scheduled event. Required to be set for event creation. + /// Sets the name of the scheduled event, replacing the current value as set in [`Self::new`]. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = name.into(); self } @@ -78,22 +100,24 @@ impl CreateScheduledEvent { self } - /// Sets the start time of the scheduled event. Required to be set for event creation. - pub fn start_time>(mut self, timestamp: T) -> Self { - self.scheduled_start_time = Some(timestamp.into().to_string()); + /// Sets the start time of the scheduled event, replacing the current value as set in + /// [`Self::new`]. + pub fn start_time(mut self, timestamp: impl Into) -> Self { + self.scheduled_start_time = timestamp.into().to_string(); self } /// Sets the end time of the scheduled event. Required if [`Self::kind`] is /// [`ScheduledEventType::External`]. - pub fn end_time>(mut self, timestamp: T) -> Self { + pub fn end_time(mut self, timestamp: impl Into) -> Self { self.scheduled_end_time = Some(timestamp.into().to_string()); self } - /// Sets the entity type of the scheduled event. Required to be set for event creation. + /// Sets the entity type of the scheduled event, replacing the current value as set in + /// [`Self::new`]. pub fn kind(mut self, kind: ScheduledEventType) -> Self { - self.entity_type = Some(kind); + self.entity_type = kind; self } @@ -133,23 +157,3 @@ impl CreateScheduledEvent { self } } - -impl Default for CreateScheduledEvent { - /// Creates a builder with default values, setting the `privacy_level` to `GUILD_ONLY`. As this - /// is the only possible value of this field, it's only used at event creation, and we don't - /// even parse it into the `ScheduledEvent` struct. - fn default() -> Self { - Self { - privacy_level: 2, - - name: None, - image: None, - channel_id: None, - description: None, - entity_type: None, - entity_metadata: None, - scheduled_end_time: None, - scheduled_start_time: None, - } - } -} From 7bde05883cefa67bc632ef63c453b00f1040df29 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Mon, 25 Jul 2022 08:59:15 -0400 Subject: [PATCH 04/11] Enforce required fields for CreateSticker --- src/builder/create_sticker.rs | 61 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/builder/create_sticker.rs b/src/builder/create_sticker.rs index 8e0ad4ce312..93236237fe2 100644 --- a/src/builder/create_sticker.rs +++ b/src/builder/create_sticker.rs @@ -11,17 +11,31 @@ use crate::model::prelude::*; /// - [`PartialGuild::create_sticker`] /// - [`Guild::create_sticker`] /// - [`GuildId::create_sticker`] -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] #[must_use] pub struct CreateSticker<'a> { - name: Option, - tags: Option, - description: Option, - - file: Option>, + name: String, + tags: String, + description: String, + file: AttachmentType<'a>, } impl<'a> CreateSticker<'a> { + /// Creates a new builder with the given data. All of this builder's fields are required. + pub fn new( + name: impl Into, + tags: impl Into, + description: impl Into, + file: impl Into>, + ) -> Self { + Self { + name: name.into(), + tags: tags.into(), + description: description.into(), + file: file.into(), + } + } + /// Creates a new sticker in the guild with the data set, if any. /// /// **Note**: Requires the [Manage Emojis and Stickers] permission. @@ -48,51 +62,44 @@ impl<'a> CreateSticker<'a> { #[cfg(feature = "http")] async fn _execute(self, http: &Http, guild_id: GuildId) -> Result { - let file = self.file.ok_or(Error::Model(ModelError::NoStickerFileSet))?; - let mut map = Vec::with_capacity(3); - if let Some(name) = self.name { - map.push(("name".to_string(), name)); - } - if let Some(tags) = self.tags { - map.push(("tags".to_string(), tags)); - } - if let Some(description) = self.description { - map.push(("description".to_string(), description)); - } + map.push(("name".to_string(), self.name)); + map.push(("tags".to_string(), self.tags)); + map.push(("description".to_string(), self.description)); - http.create_sticker(guild_id.into(), map, file, None).await + http.create_sticker(guild_id.into(), map, self.file, None).await } - /// The name of the sticker to set. + /// Set the name of the sticker, replacing the current value as set in [`Self::new`]. /// /// **Note**: Must be between 2 and 30 characters long. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = name.into(); self } - /// The description of the sticker. + /// Set the description of the sticker, replacing the current value as set in [`Self::new`]. /// /// **Note**: If not empty, must be between 2 and 100 characters long. pub fn description(mut self, description: impl Into) -> Self { - self.description = Some(description.into()); + self.description = description.into(); self } - /// The Discord name of a unicode emoji representing the sticker's expression. + /// The Discord name of a unicode emoji representing the sticker's expression. Replaces teh + /// current value as set in [`Self::new`]. /// /// **Note**: Must be between 2 and 200 characters long. pub fn tags(mut self, tags: impl Into) -> Self { - self.tags = Some(tags.into()); + self.tags = tags.into(); self } - /// The sticker file. + /// Set the sticker file. Replaces the current value as set in [`Self::new`]. /// /// **Note**: Must be a PNG, APNG, or Lottie JSON file, max 500 KB. - pub fn file>>(mut self, file: T) -> Self { - self.file = Some(file.into()); + pub fn file(mut self, file: impl Into>) -> Self { + self.file = file.into(); self } } From 41ac0fb39d86e6c9ac57ffc6b453fcf591192361 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Wed, 27 Jul 2022 17:14:05 -0400 Subject: [PATCH 05/11] Enforce required fields for CreateThread --- src/builder/create_thread.rs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/builder/create_thread.rs b/src/builder/create_thread.rs index 6d936cc2b67..1daeedf28cf 100644 --- a/src/builder/create_thread.rs +++ b/src/builder/create_thread.rs @@ -4,22 +4,30 @@ use crate::http::Http; use crate::internal::prelude::*; use crate::model::prelude::*; -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateThread { - #[serde(skip_serializing_if = "Option::is_none")] - name: Option, + name: String, #[serde(skip_serializing_if = "Option::is_none")] auto_archive_duration: Option, #[serde(skip_serializing_if = "Option::is_none")] rate_limit_per_user: Option, - #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "type")] kind: Option, } impl CreateThread { + /// Creates a builder with the given thread name, leaving all other fields empty. + pub fn new(name: impl Into) -> Self { + Self { + name: name.into(), + auto_archive_duration: None, + rate_limit_per_user: None, + kind: None, + } + } + /// Creates a thread, either private or public. Public threads require a message to connect the /// thread to. /// @@ -41,12 +49,11 @@ impl CreateThread { } } - /// The name of the thread. + /// The name of the thread. Replaces the current value as set in [`Self::new`]. /// /// **Note**: Must be between 2 and 100 characters long. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); - + self.name = name.into(); self } @@ -55,7 +62,6 @@ impl CreateThread { /// **Note**: Can only be set to 60, 1440, 4320, 10080 currently. pub fn auto_archive_duration(mut self, duration: u16) -> Self { self.auto_archive_duration = Some(duration); - self } @@ -63,7 +69,6 @@ impl CreateThread { /// /// Bots, or users with the [`MANAGE_MESSAGES`] and/or [`MANAGE_CHANNELS`] permissions are /// exempt from this restriction. - /// from this restriction. /// /// **Note**: Must be between 0 and 21600 seconds (360 minutes or 6 hours). /// @@ -72,19 +77,17 @@ impl CreateThread { #[doc(alias = "slowmode")] pub fn rate_limit_per_user(mut self, seconds: u16) -> Self { self.rate_limit_per_user = Some(seconds); - self } - /// The thread type, which can be [`ChannelType::PublicThread`] or [`ChannelType::PrivateThread`]. + /// The thread type, either [`ChannelType::PublicThread`] or [`ChannelType::PrivateThread`]. /// /// **Note**: This defaults to [`ChannelType::PrivateThread`] in order to match the behavior - /// when thread documentation was first published. This is a bit of a weird default though, - /// and thus is highly likely to change in the future, so it is recommended to always - /// explicitly setting it to avoid any breaking change. + /// when thread documentation was first published. This is a bit of a weird default though, and + /// thus is highly likely to change in the future, so it is recommended to always explicitly + /// setting it to avoid any breaking change. pub fn kind(mut self, kind: ChannelType) -> Self { self.kind = Some(kind); - self } } From 75fb6600e1d3763944e8bc28f09ae9587b76920e Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Wed, 27 Jul 2022 17:37:00 -0400 Subject: [PATCH 06/11] Enforce required fields for CreateStageInstance --- src/builder/create_stage_instance.rs | 36 ++++++++++++++++------------ 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/builder/create_stage_instance.rs b/src/builder/create_stage_instance.rs index b2a85bff5ff..1a5f7ffec5e 100644 --- a/src/builder/create_stage_instance.rs +++ b/src/builder/create_stage_instance.rs @@ -5,16 +5,22 @@ use crate::internal::prelude::*; use crate::model::prelude::*; /// Builder for creating a [`StageInstance`]. -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateStageInstance { - #[serde(skip_serializing_if = "Option::is_none")] - channel_id: Option, - #[serde(skip_serializing_if = "Option::is_none")] - topic: Option, + channel_id: ChannelId, + topic: String, } impl CreateStageInstance { + /// Creates a builder with the provided Channel Id and topic. + pub fn new(channel_id: impl Into, topic: impl Into) -> Self { + Self { + channel_id: channel_id.into(), + topic: topic.into(), + } + } + /// Creates the stage instance. /// /// # Errors @@ -27,12 +33,10 @@ impl CreateStageInstance { pub async fn execute(self, cache_http: impl CacheHttp) -> Result { #[cfg(feature = "cache")] { - if let Some(channel_id) = self.channel_id { - if let Some(cache) = cache_http.cache() { - if let Some(channel) = cache.guild_channel(channel_id) { - if channel.kind != ChannelType::Stage { - return Err(Error::Model(ModelError::InvalidChannelType)); - } + if let Some(cache) = cache_http.cache() { + if let Some(channel) = cache.guild_channel(self.channel_id) { + if channel.kind != ChannelType::Stage { + return Err(Error::Model(ModelError::InvalidChannelType)); } } } @@ -46,15 +50,17 @@ impl CreateStageInstance { http.create_stage_instance(&self).await } - /// Sets the stage channel id of the stage channel instance. + /// Sets the stage channel id of the stage channel instance, replacing the current value as set + /// in [`Self::new`]. pub fn channel_id(mut self, id: impl Into) -> Self { - self.channel_id = Some(id.into()); + self.channel_id = id.into(); self } - /// Sets the topic of the stage channel instance. + /// Sets the topic of the stage channel instance, replacing the current value as set in + /// [`Self::new`]. pub fn topic(mut self, topic: impl Into) -> Self { - self.topic = Some(topic.into()); + self.topic = topic.into(); self } } From c49088840b2f13675e1ffc844862e48c9afa865f Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Wed, 27 Jul 2022 17:48:57 -0400 Subject: [PATCH 07/11] Enforce required fields for CreateWebhook --- src/builder/create_webhook.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/builder/create_webhook.rs b/src/builder/create_webhook.rs index 8f9ca2b561a..42910124d8a 100644 --- a/src/builder/create_webhook.rs +++ b/src/builder/create_webhook.rs @@ -5,16 +5,23 @@ use crate::internal::prelude::*; #[cfg(feature = "http")] use crate::model::prelude::*; -#[derive(Debug, Default, Clone, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateWebhook { - #[serde(skip_serializing_if = "Option::is_none")] - name: Option, + name: String, #[serde(skip_serializing_if = "Option::is_none")] avatar: Option, } impl CreateWebhook { + /// Creates a new builder with the given webhook name, leaving all other fields empty. + pub fn new(name: impl Into) -> Self { + Self { + name: name.into(), + avatar: None, + } + } + /// Creates the webhook. /// /// # Errors @@ -52,22 +59,20 @@ impl CreateWebhook { #[cfg(feature = "http")] async fn _execute(self, http: &Http, channel_id: ChannelId) -> Result { - if let Some(name) = &self.name { - if name.len() < 2 { - return Err(Error::Model(ModelError::NameTooShort)); - } else if name.len() > 100 { - return Err(Error::Model(ModelError::NameTooLong)); - } + if self.name.len() < 2 { + return Err(Error::Model(ModelError::NameTooShort)); + } else if self.name.len() > 100 { + return Err(Error::Model(ModelError::NameTooLong)); } http.create_webhook(channel_id.into(), &self, None).await } - /// Set the webhook's name. + /// Set the webhook's name, replacing the current value as set in [`Self::new`]. /// /// This must be between 1-80 characters. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = name.into(); self } From 88224f45d833a26b56fd2adb467ba76cd902b26b Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Thu, 28 Jul 2022 23:38:19 -0400 Subject: [PATCH 08/11] Enforce required fields for application command builders --- examples/e14_slash_commands/src/main.rs | 53 ++++-------- src/builder/create_application_command.rs | 99 ++++++++++++++++------- src/model/application/command.rs | 17 ++-- 3 files changed, 89 insertions(+), 80 deletions(-) diff --git a/examples/e14_slash_commands/src/main.rs b/examples/e14_slash_commands/src/main.rs index 1b0609b5725..a9de03528ab 100644 --- a/examples/e14_slash_commands/src/main.rs +++ b/examples/e14_slash_commands/src/main.rs @@ -74,37 +74,25 @@ impl EventHandler for Handler { .expect("GUILD_ID must be an integer"), ); - let c1 = CreateCommand::default().name("ping").description("A ping command"); - - let c2 = CreateCommand::default().name("id").description("Get a user id").add_option( - CreateOption::default() - .name("id") - .description("The user to lookup") - .kind(CommandOptionType::User) - .required(true), + let c1 = CreateCommand::new("ping", "A ping command"); + + let c2 = CreateCommand::new("id", "Get a user id").add_option( + CreateOption::new(CommandOptionType::User, "id", "The user to lookup").required(true), ); - let c3 = CreateCommand::default() - .name("welcome") + let c3 = CreateCommand::new("welcome", "Welcome a user") .name_localized("de", "begrüßen") - .description("Welcome a user") .description_localized("de", "Einen Nutzer begrüßen") .add_option( - CreateOption::default() - .name("user") + CreateOption::new(CommandOptionType::User, "user", "The user to welcome") .name_localized("de", "nutzer") - .description("The user to welcome") .description_localized("de", "Der zu begrüßende Nutzer") - .kind(CommandOptionType::User) .required(true), ) .add_option( - CreateOption::default() - .name("message") + CreateOption::new(CommandOptionType::String, "message", "The message to send") .name_localized("de", "nachricht") - .description("The message to send") .description_localized("de", "Die versendete Nachricht") - .kind(CommandOptionType::String) .required(true) .add_string_choice_localized( "Welcome to our cool server! Ask me if you need help", @@ -128,36 +116,23 @@ impl EventHandler for Handler { ), ); - let c4 = CreateCommand::default() - .name("numberinput") - .description("Test command for number input") + let c4 = CreateCommand::new("numberinput", "Test command for number input") .add_option( - CreateOption::default() - .name("int") - .description("An integer from 5 to 10") - .kind(CommandOptionType::Integer) + CreateOption::new(CommandOptionType::Integer, "int", "An integer fro 5 to 10") .min_int_value(5) .max_int_value(10) .required(true), ) .add_option( - CreateOption::default() - .name("number") - .description("A float from -3.3 to 234.5") - .kind(CommandOptionType::Number) - .min_number_value(-3.3) + CreateOption::new(CommandOptionType::Number, "number", "A float from -3 to 234.5") + .min_number_value(-3.0) .max_number_value(234.5) .required(true), ); - let c5 = CreateCommand::default() - .name("attachmentinput") - .description("Test command for attachment input") + let c5 = CreateCommand::new("attachmentinput", "Test command for attachment input") .add_option( - CreateOption::default() - .name("attachment") - .description("A file") - .kind(CommandOptionType::Attachment) + CreateOption::new(CommandOptionType::Attachment, "attachment", "A file") .required(true), ); @@ -167,7 +142,7 @@ impl EventHandler for Handler { let guild_command = Command::create_global_application_command( &ctx.http, - CreateCommand::default().name("wonderful_command").description("An amazing command"), + CreateCommand::new("wonderful_command", "An amazing command"), ) .await; diff --git a/src/builder/create_application_command.rs b/src/builder/create_application_command.rs index b2d677769d8..fa4fa4ed1fa 100644 --- a/src/builder/create_application_command.rs +++ b/src/builder/create_application_command.rs @@ -27,17 +27,14 @@ enum Number { /// [`Self::kind`], [`Self::name`], and [`Self::description`] are required fields. /// /// [`CommandOption`]: crate::model::application::command::CommandOption -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateApplicationCommandOption { - #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "type")] - kind: Option, - #[serde(skip_serializing_if = "Option::is_none")] - name: Option, + kind: CommandOptionType, + name: String, name_localizations: HashMap, - #[serde(skip_serializing_if = "Option::is_none")] - description: Option, + description: String, description_localizations: HashMap, #[serde(skip_serializing_if = "Option::is_none")] default: Option, @@ -60,24 +57,53 @@ pub struct CreateApplicationCommandOption { } impl CreateApplicationCommandOption { - /// Sets the `CommandOptionType`. + /// Creates a new builder with the given option type, name, and description, leaving all other + /// fields empty. + pub fn new( + kind: CommandOptionType, + name: impl Into, + description: impl Into, + ) -> Self { + Self { + kind, + name: name.into(), + name_localizations: HashMap::new(), + description: description.into(), + description_localizations: HashMap::new(), + default: None, + required: None, + autocomplete: None, + min_value: None, + max_value: None, + min_length: None, + max_length: None, + + channel_types: Vec::new(), + choices: Vec::new(), + options: Vec::new(), + } + } + + /// Sets the `CommandOptionType`, replacing the current value as set in [`Self::new`]. pub fn kind(mut self, kind: CommandOptionType) -> Self { - self.kind = Some(kind); + self.kind = kind; self } - /// Sets the name of the option. + /// Sets the name of the option, replacing the current value as set in [`Self::new`]. /// /// **Note**: Must be between 1 and 32 lowercase characters, matching `r"^[\w-]{1,32}$"`. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = name.into(); self } /// Specifies a localized name of the option. /// /// ```rust - /// # serenity::builder::CreateApplicationCommandOption::default() + /// # use serenity::builder::CreateApplicationCommandOption; + /// # use serenity::model::application::command::CommandOptionType; + /// # CreateApplicationCommandOption::new(CommandOptionType::Integer, "", "") /// .name("age") /// .name_localized("zh-CN", "岁数") /// # ; @@ -87,18 +113,19 @@ impl CreateApplicationCommandOption { self } - /// Sets the description for the option. + /// Sets the description for the option, replacing the current value as set in [`Self::new]`. /// /// **Note**: Must be between 1 and 100 characters. pub fn description(mut self, description: impl Into) -> Self { - self.description = Some(description.into()); + self.description = description.into(); self } - /// Specifies a localized description of the option. /// /// ```rust - /// # serenity::builder::CreateApplicationCommandOption::default() + /// # use serenity::builder::CreateApplicationCommandOption; + /// # use serenity::model::application::command::CommandOptionType; + /// # CreateApplicationCommandOption::new(CommandOptionType::String, "", "") /// .description("Wish a friend a happy birthday") /// .description_localized("zh-CN", "祝你朋友生日快乐") /// # ; @@ -289,18 +316,16 @@ impl CreateApplicationCommandOption { /// [`Self::name`] and [`Self::description`] are required fields. /// /// [`Command`]: crate::model::application::command::Command -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateApplicationCommand { #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "type")] kind: Option, - #[serde(skip_serializing_if = "Option::is_none")] - name: Option, + name: String, name_localizations: HashMap, - #[serde(skip_serializing_if = "Option::is_none")] - description: Option, + description: String, description_localizations: HashMap, #[serde(skip_serializing_if = "Option::is_none")] default_member_permissions: Option, @@ -311,6 +336,22 @@ pub struct CreateApplicationCommand { } impl CreateApplicationCommand { + /// Creates a new builder with the given name and description, leaving all other fields empty. + pub fn new(name: impl Into, description: impl Into) -> Self { + Self { + kind: None, + + name: name.into(), + name_localizations: HashMap::new(), + description: description.into(), + description_localizations: HashMap::new(), + default_member_permissions: None, + dm_permission: None, + + options: Vec::new(), + } + } + /// Create a [`Command`], overriding an existing one with the same name if it exists. /// /// Providing a `command_id` will edit the corresponding command. @@ -347,20 +388,21 @@ impl CreateApplicationCommand { } } - /// Specifies the name of the application command. + /// Specifies the name of the application command, replacing the current value as set in + /// [`Self::new]`. /// /// **Note**: Must be between 1 and 32 lowercase characters, matching `r"^[\w-]{1,32}$"`. Two /// global commands of the same app cannot have the same name. Two guild-specific commands of /// the same app cannot have the same name. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = name.into(); self } /// Specifies a localized name of the application command. /// /// ```rust - /// # serenity::builder::CreateApplicationCommand::default() + /// # serenity::builder::CreateApplicationCommand::new("", "") /// .name("birthday") /// .name_localized("zh-CN", "生日") /// .name_localized("el", "γενέθλια") @@ -386,22 +428,22 @@ impl CreateApplicationCommand { /// Specifies if the command is available in DMs. pub fn dm_permission(mut self, enabled: bool) -> Self { self.dm_permission = Some(enabled); - self } - /// Specifies the description of the application command. + /// Specifies the description of the application command, replacing the current value as set in + /// [`Self::new`]. /// /// **Note**: Must be between 1 and 100 characters long. pub fn description(mut self, description: impl Into) -> Self { - self.description = Some(description.into()); + self.description = description.into(); self } /// Specifies a localized description of the application command. /// /// ```rust - /// # serenity::builder::CreateApplicationCommand::default() + /// # serenity::builder::CreateApplicationCommand::new("", "") /// .description("Wish a friend a happy birthday") /// .description_localized("zh-CN", "祝你朋友生日快乐") /// # ; @@ -409,7 +451,6 @@ impl CreateApplicationCommand { pub fn description_localized( mut self, locale: impl Into, - description: impl Into, ) -> Self { self.description_localizations.insert(locale.into(), description.into()); diff --git a/src/model/application/command.rs b/src/model/application/command.rs index 0a378ec867a..831f3ebe4c0 100644 --- a/src/model/application/command.rs +++ b/src/model/application/command.rs @@ -105,8 +105,7 @@ impl Command { /// use serenity::model::application::command::Command; /// use serenity::model::id::ApplicationId; /// - /// let builder = - /// CreateApplicationCommand::default().name("ping").description("A simple ping command"); + /// let builder = CreateApplicationCommand::new("ping", "A simple ping command"); /// let _ = Command::create_global_application_command(&http, builder).await; /// # } /// ``` @@ -126,16 +125,10 @@ impl Command { /// use serenity::model::application::command::{Command, CommandOptionType}; /// use serenity::model::id::ApplicationId; /// - /// let builder = CreateApplicationCommand::default() - /// .name("echo") - /// .description("Makes the bot send a message") - /// .add_option( - /// CreateOption::default() - /// .name("message") - /// .description("The message to send") - /// .kind(CommandOptionType::String) - /// .required(true), - /// ); + /// let builder = CreateApplicationCommand::new("echo", "Makes the bot send a message").add_option( + /// CreateOption::new(CommandOptionType::String, "message", "The message to send") + /// .required(true), + /// ); /// let _ = Command::create_global_application_command(&http, builder).await; /// # } /// ``` From b9755eb5bd0321fcdbb65b372df020c60bec807f Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Mon, 8 Aug 2022 14:21:38 -0400 Subject: [PATCH 09/11] Enforce required fields for message components builders --- examples/e17_message_components/src/main.rs | 23 ++-- src/builder/create_components.rs | 120 +++++++++++--------- 2 files changed, 78 insertions(+), 65 deletions(-) diff --git a/examples/e17_message_components/src/main.rs b/examples/e17_message_components/src/main.rs index 3216a397c6b..42620df49b1 100644 --- a/examples/e17_message_components/src/main.rs +++ b/examples/e17_message_components/src/main.rs @@ -68,23 +68,22 @@ impl Animal { } fn menu_option(&self) -> CreateSelectMenuOption { - CreateSelectMenuOption::default() + CreateSelectMenuOption::new( // This is what will be shown to the user - .label(format!("{} {}", self.emoji(), self)) + format!("{} {}", self.emoji(), self), // This is used to identify the selected value - .value(self.to_string().to_ascii_lowercase()) + self.to_string().to_ascii_lowercase(), + ) } fn select_menu() -> CreateSelectMenu { - CreateSelectMenu::default() - .custom_id("animal_select") - .placeholder("No animal selected") - .options(vec![ - Self::Cat.menu_option(), - Self::Dog.menu_option(), - Self::Horse.menu_option(), - Self::Alpaca.menu_option(), - ]) + CreateSelectMenu::new("animal_select", vec![ + Self::Cat.menu_option(), + Self::Dog.menu_option(), + Self::Horse.menu_option(), + Self::Alpaca.menu_option(), + ]) + .placeholder("No animal selected") } fn action_row() -> CreateActionRow { diff --git a/src/builder/create_components.rs b/src/builder/create_components.rs index e5ee5cae55e..73a28361e28 100644 --- a/src/builder/create_components.rs +++ b/src/builder/create_components.rs @@ -87,6 +87,7 @@ impl CreateActionRow { #[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateButton { + style: ButtonStyle, #[serde(skip_serializing_if = "Option::is_none")] label: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -97,7 +98,6 @@ pub struct CreateButton { emoji: Option, #[serde(skip_serializing_if = "Option::is_none")] disabled: Option, - style: ButtonStyle, #[serde(rename = "type")] kind: u8, @@ -108,17 +108,22 @@ impl Default for CreateButton { fn default() -> Self { Self { style: ButtonStyle::Primary, - custom_id: None, - disabled: None, label: None, - emoji: None, + custom_id: None, url: None, + emoji: None, + disabled: None, kind: 2, } } } impl CreateButton { + // Creates a primary button. Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Sets the style of the button. pub fn style(mut self, kind: ButtonStyle) -> Self { self.style = kind; @@ -162,47 +167,46 @@ impl CreateButton { #[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateSelectMenu { + custom_id: String, #[serde(skip_serializing_if = "Option::is_none")] placeholder: Option, #[serde(skip_serializing_if = "Option::is_none")] - custom_id: Option, - #[serde(skip_serializing_if = "Option::is_none")] min_values: Option, #[serde(skip_serializing_if = "Option::is_none")] max_values: Option, #[serde(skip_serializing_if = "Option::is_none")] disabled: Option, - #[serde(skip_serializing_if = "Option::is_none")] - options: Option>, + options: Vec, #[serde(rename = "type")] kind: u8, } -impl Default for CreateSelectMenu { - fn default() -> Self { +impl CreateSelectMenu { + // Creates a builder with given custom id (a developer-defined identifier), and a list of + // options, leaving all other fields empty. + pub fn new(custom_id: impl Into, options: Vec) -> Self { Self { + custom_id: custom_id.into(), placeholder: None, min_values: None, max_values: None, - custom_id: None, disabled: None, - options: None, + options, kind: 3, } } -} -impl CreateSelectMenu { /// The placeholder of the select menu. pub fn placeholder(mut self, label: impl Into) -> Self { self.placeholder = Some(label.into()); self } - /// Sets the custom id of the select menu, a developer-defined identifier. + /// Sets the custom id of the select menu, a developer-defined identifier. Replaces the current + /// value as set in [`Self::new`]. pub fn custom_id(mut self, id: impl Into) -> Self { - self.custom_id = Some(id.into()); + self.custom_id = id.into(); self } @@ -225,7 +229,7 @@ impl CreateSelectMenu { } pub fn options(mut self, options: Vec) -> Self { - self.options = Some(options); + self.options = options; self } } @@ -233,13 +237,11 @@ impl CreateSelectMenu { /// A builder for creating a [`SelectMenuOption`]. /// /// [`SelectMenuOption`]: crate::model::application::component::SelectMenuOption -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateSelectMenuOption { - #[serde(skip_serializing_if = "Option::is_none")] - label: Option, - #[serde(skip_serializing_if = "Option::is_none")] - value: Option, + label: String, + value: String, #[serde(skip_serializing_if = "Option::is_none")] description: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -249,20 +251,27 @@ pub struct CreateSelectMenuOption { } impl CreateSelectMenuOption { - /// Creates an option. + /// Creates a select menu option with the given label and value, leaving all other fields + /// empty. pub fn new(label: impl Into, value: impl Into) -> Self { - Self::default().label(label).value(value) + Self { + label: label.into(), + value: value.into(), + description: None, + emoji: None, + default: None, + } } - /// Sets the label of this option. + /// Sets the label of this option, replacing the current value as set in [`Self::new`]. pub fn label(mut self, label: impl Into) -> Self { - self.label = Some(label.into()); + self.label = label.into(); self } - /// Sets the value of this option. + /// Sets the value of this option, replacing the current value as set in [`Self::new`]. pub fn value(mut self, value: impl Into) -> Self { - self.value = Some(value.into()); + self.value = value.into(); self } @@ -291,12 +300,10 @@ impl CreateSelectMenuOption { #[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateInputText { - #[serde(skip_serializing_if = "Option::is_none")] - custom_id: Option, - #[serde(skip_serializing_if = "Option::is_none")] - style: Option, - #[serde(skip_serializing_if = "Option::is_none")] - label: Option, + style: InputTextStyle, + label: String, + custom_id: String, + #[serde(skip_serializing_if = "Option::is_none")] placeholder: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -312,38 +319,45 @@ pub struct CreateInputText { kind: u8, } -impl Default for CreateInputText { - fn default() -> Self { +impl CreateInputText { + /// Creates a text input with the given style, label, and custom id (a developer-defined + /// identifier), leaving all other fields empty. + pub fn new( + style: InputTextStyle, + label: impl Into, + custom_id: impl Into, + ) -> Self { Self { - value: None, - style: None, - label: None, - required: None, - custom_id: None, + style, + label: label.into(), + custom_id: custom_id.into(), + placeholder: None, min_length: None, max_length: None, - kind: 4_u8, + value: None, + required: None, + + kind: 4, } } -} -impl CreateInputText { - /// Sets the custom id of the input text, a developer-defined identifier. - pub fn custom_id(mut self, id: impl Into) -> Self { - self.custom_id = Some(id.into()); + /// Sets the style of this input text. Replaces the current value as set in [`Self::new`]. + pub fn style(mut self, kind: InputTextStyle) -> Self { + self.style = kind; self } - /// Sets the style of this input text - pub fn style(mut self, kind: InputTextStyle) -> Self { - self.style = Some(kind); + /// Sets the label of this input text. Replaces the current value as set in [`Self::new`]. + pub fn label(mut self, label: impl Into) -> Self { + self.label = label.into(); self } - /// Sets the label of this input text. - pub fn label(mut self, label: impl Into) -> Self { - self.label = Some(label.into()); + /// Sets the custom id of the input text, a developer-defined identifier. Replaces the current + /// value as set in [`Self::new`]. + pub fn custom_id(mut self, id: impl Into) -> Self { + self.custom_id = id.into(); self } From c4380f83f97150a48d36030bf1acb6d3c40668d0 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Mon, 8 Aug 2022 17:42:57 -0400 Subject: [PATCH 10/11] Enforce required fields for embeds --- .../e09_create_message_builder/src/main.rs | 2 +- src/builder/create_embed.rs | 70 +++++++++++-------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/examples/e09_create_message_builder/src/main.rs b/examples/e09_create_message_builder/src/main.rs index 0ee38ea36ad..3531c73ac1f 100644 --- a/examples/e09_create_message_builder/src/main.rs +++ b/examples/e09_create_message_builder/src/main.rs @@ -17,7 +17,7 @@ impl EventHandler for Handler { // using a builder syntax. // This example will create a message that says "Hello, World!", with an embed that has // a title, description, an image, three fields, and a footer. - let footer = CreateEmbedFooter::default().text("This is a footer"); + let footer = CreateEmbedFooter::new("This is a footer"); let embed = CreateEmbed::default() .title("This is a title") .description("This is a description") diff --git a/src/builder/create_embed.rs b/src/builder/create_embed.rs index 6f9bef856cb..8af61beeeee 100644 --- a/src/builder/create_embed.rs +++ b/src/builder/create_embed.rs @@ -219,9 +219,8 @@ impl CreateEmbed { /// let channel_search = channels.values().find(|c| c.name == "join-log"); /// /// if let Some(channel) = channel_search { - /// let author = CreateEmbedAuthor::default() - /// .icon_url(member.user.face()) - /// .name(member.user.name); + /// let icon_url = member.user.face(); + /// let author = CreateEmbedAuthor::new(member.user.name).icon_url(icon_url); /// let mut embed = CreateEmbed::default().title("Member Join").author(author); /// if let Some(joined_at) = member.joined_at { /// embed = embed.timestamp(joined_at); @@ -279,9 +278,7 @@ impl CreateEmbed { pub(super) fn check_length(&self) -> Result<()> { let mut length = 0; if let Some(ref author) = self.author { - if let Some(ref name) = author.name { - length += name.chars().count(); - } + length += author.name.chars().count(); } if let Some(ref description) = self.description { @@ -294,9 +291,7 @@ impl CreateEmbed { } if let Some(ref footer) = self.footer { - if let Some(ref text) = footer.text { - length += text.chars().count(); - } + length += footer.text.chars().count(); } if let Some(ref title) = self.title { @@ -375,29 +370,35 @@ impl From for CreateEmbed { /// A builder to create a fake [`Embed`] object's author, for use with the [`CreateEmbed::author`] /// method. -/// -/// Requires that you specify a [`Self::name`]. -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateEmbedAuthor { + name: String, #[serde(skip_serializing_if = "Option::is_none")] icon_url: Option, #[serde(skip_serializing_if = "Option::is_none")] - name: Option, - #[serde(skip_serializing_if = "Option::is_none")] url: Option, } impl CreateEmbedAuthor { - /// Set the URL of the author's icon. - pub fn icon_url(mut self, icon_url: impl Into) -> Self { - self.icon_url = Some(icon_url.into()); - self + /// Creates an author object with the given name, leaving all other fields empty. + pub fn new(name: impl Into) -> Self { + Self { + name: name.into(), + icon_url: None, + url: None, + } } - /// Set the author's name. + /// Set the author's name, replacing the current value as set in [`Self::new`]. pub fn name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = name.into(); + self + } + + /// Set the URL of the author's icon. + pub fn icon_url(mut self, icon_url: impl Into) -> Self { + self.icon_url = Some(icon_url.into()); self } @@ -411,8 +412,8 @@ impl CreateEmbedAuthor { impl From for CreateEmbedAuthor { fn from(author: EmbedAuthor) -> Self { Self { + name: author.name, icon_url: author.icon_url, - name: Some(author.name), url: author.url, } } @@ -422,25 +423,32 @@ impl From for CreateEmbedAuthor { /// method. /// /// This does not have any required fields. -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[must_use] pub struct CreateEmbedFooter { + text: String, #[serde(skip_serializing_if = "Option::is_none")] icon_url: Option, - #[serde(skip_serializing_if = "Option::is_none")] - text: Option, } impl CreateEmbedFooter { - /// Set the icon URL's value. This only supports HTTP(S). - pub fn icon_url(mut self, icon_url: impl Into) -> Self { - self.icon_url = Some(icon_url.into()); - self + // Creates a new footer object with the given text, leaving all other fields empty. + pub fn new(text: impl Into) -> Self { + Self { + text: text.into(), + icon_url: None, + } } - /// Set the footer's text. + /// Set the footer's text, replacing the current value as set in [`Self::new`]. pub fn text(mut self, text: impl Into) -> Self { - self.text = Some(text.into()); + self.text = text.into(); + self + } + + /// Set the icon URL's value. This only supports HTTP(S). + pub fn icon_url(mut self, icon_url: impl Into) -> Self { + self.icon_url = Some(icon_url.into()); self } } @@ -449,7 +457,7 @@ impl From for CreateEmbedFooter { fn from(footer: EmbedFooter) -> Self { Self { icon_url: footer.icon_url, - text: Some(footer.text), + text: footer.text, } } } From 4bb2d97a5ce9aeaf1b931cb930ad6fb5b52f24a5 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Tue, 9 Aug 2022 11:42:13 -0400 Subject: [PATCH 11/11] Introduce `Self::new` wrapper methods for remaining builders These methods simply wrap `Self::default`. Also change any remaining usages of `Builder::default` over to `Builder::new`. --- examples/e03_struct_utilities/src/main.rs | 2 +- examples/e05_command_framework/src/main.rs | 2 +- .../e09_create_message_builder/src/main.rs | 4 +-- examples/e13_parallel_loops/src/main.rs | 4 +-- examples/e14_slash_commands/src/main.rs | 4 +-- examples/e17_message_components/src/main.rs | 20 +++++------ examples/e18_webhook/src/main.rs | 2 +- src/builder/bot_auth_parameters.rs | 5 +++ src/builder/create_allowed_mentions.rs | 21 ++++++----- .../create_application_command_permission.rs | 10 ++++++ src/builder/create_components.rs | 10 ++++++ src/builder/create_embed.rs | 13 ++++--- src/builder/create_interaction_response.rs | 17 ++++++++- .../create_interaction_response_followup.rs | 5 +++ src/builder/create_invite.rs | 15 +++++--- src/builder/create_message.rs | 8 +++-- src/builder/edit_automod_rule.rs | 7 ++++ src/builder/edit_channel.rs | 9 +++-- src/builder/edit_guild.rs | 11 ++++-- src/builder/edit_guild_welcome_screen.rs | 5 +++ src/builder/edit_guild_widget.rs | 5 +++ src/builder/edit_interaction_response.rs | 5 +++ src/builder/edit_member.rs | 5 +++ src/builder/edit_message.rs | 7 +++- src/builder/edit_profile.rs | 11 +++--- src/builder/edit_role.rs | 35 +++++++++++-------- src/builder/edit_scheduled_event.rs | 5 +++ src/builder/edit_stage_instance.rs | 5 +++ src/builder/edit_sticker.rs | 5 +++ src/builder/edit_thread.rs | 5 +++ src/builder/edit_voice_state.rs | 5 +++ src/builder/edit_webhook.rs | 5 +++ src/builder/edit_webhook_message.rs | 5 +++ src/builder/execute_webhook.rs | 23 +++++++----- src/builder/get_messages.rs | 7 +++- src/framework/standard/help_commands.rs | 16 ++++----- .../interaction/application_command.rs | 2 +- .../interaction/message_component.rs | 4 +-- src/model/application/interaction/modal.rs | 4 +-- src/model/channel/channel_category.rs | 2 +- src/model/channel/channel_id.rs | 10 +++--- src/model/channel/guild_channel.rs | 8 ++--- src/model/channel/message.rs | 6 ++-- src/model/guild/guild_id.rs | 12 +++---- src/model/guild/member.rs | 8 ++--- src/model/guild/mod.rs | 4 +-- src/model/guild/partial_guild.rs | 2 +- src/model/mention.rs | 2 +- src/model/sticker/mod.rs | 2 +- src/model/user.rs | 6 ++-- src/model/webhook.rs | 8 ++--- 51 files changed, 280 insertions(+), 123 deletions(-) diff --git a/examples/e03_struct_utilities/src/main.rs b/examples/e03_struct_utilities/src/main.rs index 3ac64c51cb9..62fc15c8fd7 100644 --- a/examples/e03_struct_utilities/src/main.rs +++ b/examples/e03_struct_utilities/src/main.rs @@ -20,7 +20,7 @@ impl EventHandler for Handler { // In this case, you can direct message a User directly by simply // calling a method on its instance, with the content of the // message. - let builder = CreateMessage::default().content("Hello!"); + let builder = CreateMessage::new().content("Hello!"); let dm = msg.author.dm(&context, builder).await; if let Err(why) = dm { diff --git a/examples/e05_command_framework/src/main.rs b/examples/e05_command_framework/src/main.rs index 638b649d8ac..158f9030d7b 100644 --- a/examples/e05_command_framework/src/main.rs +++ b/examples/e05_command_framework/src/main.rs @@ -565,7 +565,7 @@ async fn am_i_admin(ctx: &Context, msg: &Message, _args: Args) -> CommandResult #[command] async fn slow_mode(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { let say_content = if let Ok(slow_mode_rate_seconds) = args.single::() { - let builder = EditChannel::default().rate_limit_per_user(slow_mode_rate_seconds); + let builder = EditChannel::new().rate_limit_per_user(slow_mode_rate_seconds); if let Err(why) = msg.channel_id.edit(&ctx.http, builder).await { println!("Error setting channel's slow mode rate: {:?}", why); diff --git a/examples/e09_create_message_builder/src/main.rs b/examples/e09_create_message_builder/src/main.rs index 3531c73ac1f..496c46487f8 100644 --- a/examples/e09_create_message_builder/src/main.rs +++ b/examples/e09_create_message_builder/src/main.rs @@ -18,7 +18,7 @@ impl EventHandler for Handler { // This example will create a message that says "Hello, World!", with an embed that has // a title, description, an image, three fields, and a footer. let footer = CreateEmbedFooter::new("This is a footer"); - let embed = CreateEmbed::default() + let embed = CreateEmbed::new() .title("This is a title") .description("This is a description") .image("attachment://ferris_eyes.png") @@ -31,7 +31,7 @@ impl EventHandler for Handler { // Add a timestamp for the current time // This also accepts a rfc3339 Timestamp .timestamp(Timestamp::now()); - let builder = CreateMessage::default() + let builder = CreateMessage::new() .content("Hello, World!") .embed(embed) .add_file("./ferris_eyes.png"); diff --git a/examples/e13_parallel_loops/src/main.rs b/examples/e13_parallel_loops/src/main.rs index 8f0d0a1ca9c..86002ebeffb 100644 --- a/examples/e13_parallel_loops/src/main.rs +++ b/examples/e13_parallel_loops/src/main.rs @@ -80,7 +80,7 @@ async fn log_system_load(ctx: Arc) { // We can use ChannelId directly to send a message to a specific channel; in this case, the // message would be sent to the #testing channel on the discord server. - let embed = CreateEmbed::default() + let embed = CreateEmbed::new() .title("System Resource Load") .field("CPU Load Average", &format!("{:.2}%", cpu_load.one * 10.0), false) .field( @@ -92,7 +92,7 @@ async fn log_system_load(ctx: Arc) { ), false, ); - let builder = CreateMessage::default().embed(embed); + let builder = CreateMessage::new().embed(embed); let message = ChannelId::new(381926291785383946).send_message(&ctx, builder).await; if let Err(why) = message { eprintln!("Error sending message: {:?}", why); diff --git a/examples/e14_slash_commands/src/main.rs b/examples/e14_slash_commands/src/main.rs index a9de03528ab..1653f87e68e 100644 --- a/examples/e14_slash_commands/src/main.rs +++ b/examples/e14_slash_commands/src/main.rs @@ -54,8 +54,8 @@ impl EventHandler for Handler { _ => "not implemented :(".to_string(), }; - let data = CreateInteractionResponseData::default().content(content); - let builder = CreateInteractionResponse::default() + let data = CreateInteractionResponseData::new().content(content); + let builder = CreateInteractionResponse::new() .kind(InteractionResponseType::ChannelMessageWithSource) .interaction_response_data(data); if let Err(why) = command.create_interaction_response(&ctx.http, builder).await { diff --git a/examples/e17_message_components/src/main.rs b/examples/e17_message_components/src/main.rs index 42620df49b1..71991a3e847 100644 --- a/examples/e17_message_components/src/main.rs +++ b/examples/e17_message_components/src/main.rs @@ -88,7 +88,7 @@ impl Animal { fn action_row() -> CreateActionRow { // A select menu must be the only thing in an action row! - CreateActionRow::default().add_select_menu(Self::select_menu()) + CreateActionRow::new().add_select_menu(Self::select_menu()) } } @@ -122,7 +122,7 @@ impl Sound { } fn button(&self) -> CreateButton { - CreateButton::default() + CreateButton::new() .custom_id(self.to_string().to_ascii_lowercase()) .emoji(self.emoji()) .label(self.to_string()) @@ -131,7 +131,7 @@ impl Sound { fn action_row() -> CreateActionRow { // We can add up to 5 buttons per action row - CreateActionRow::default() + CreateActionRow::new() .add_button(Sound::Meow.button()) .add_button(Sound::Woof.button()) .add_button(Sound::Neigh.button()) @@ -163,8 +163,8 @@ impl EventHandler for Handler { } // Ask the user for its favorite animal - let components = CreateComponents::default().add_action_row(Animal::action_row()); - let builder = CreateMessage::default() + let components = CreateComponents::new().add_action_row(Animal::action_row()); + let builder = CreateMessage::new() .content("Please select your favorite animal") .components(components); let m = msg.channel_id.send_message(&ctx, builder).await.unwrap(); @@ -189,11 +189,11 @@ impl EventHandler for Handler { let animal = Animal::from_str(mci.data.values.get(0).unwrap()).unwrap(); // Acknowledge the interaction and edit the message - let components = CreateComponents::default().add_action_row(Sound::action_row()); - let data = CreateInteractionResponseData::default() + let components = CreateComponents::new().add_action_row(Sound::action_row()); + let data = CreateInteractionResponseData::new() .content(format!("You chose: **{}**\nNow choose a sound!", animal)) .components(components); - let builder = CreateInteractionResponse::default() + let builder = CreateInteractionResponse::new() .kind(InteractionResponseType::UpdateMessage) .interaction_response_data(data); mci.create_interaction_response(&ctx, builder).await.unwrap(); @@ -208,11 +208,11 @@ impl EventHandler for Handler { while let Some(mci) = cib.next().await { let sound = Sound::from_str(&mci.data.custom_id).unwrap(); // Acknowledge the interaction and send a reply - let data = CreateInteractionResponseData::default() + let data = CreateInteractionResponseData::new() .content(format!("The **{}** says __{}__", animal, sound)) // Make the message hidden for other users by setting `ephemeral(true)`. .ephemeral(true); - let builder = CreateInteractionResponse::default() + let builder = CreateInteractionResponse::new() // This time we don't edit the message, but reply to it. .kind(InteractionResponseType::ChannelMessageWithSource) .interaction_response_data(data); diff --git a/examples/e18_webhook/src/main.rs b/examples/e18_webhook/src/main.rs index 7a3131f2b05..2a3418238f1 100644 --- a/examples/e18_webhook/src/main.rs +++ b/examples/e18_webhook/src/main.rs @@ -8,6 +8,6 @@ async fn main() { let http = Http::new(""); let webhook = Webhook::from_url(&http, "https://discord.com/api/webhooks/133742013374206969/hello-there-oPNtRN5UY5DVmBe7m1N0HE-replace-me-Dw9LRkgq3zI7LoW3Rb-k-q").await.expect("Replace the webhook with your own"); - let builder = ExecuteWebhook::default().content("hello there").username("Webhook test"); + let builder = ExecuteWebhook::new().content("hello there").username("Webhook test"); webhook.execute(&http, false, builder).await.expect("Could not execute webhook."); } diff --git a/src/builder/bot_auth_parameters.rs b/src/builder/bot_auth_parameters.rs index d24e46997f9..c18ad779925 100644 --- a/src/builder/bot_auth_parameters.rs +++ b/src/builder/bot_auth_parameters.rs @@ -19,6 +19,11 @@ pub struct CreateBotAuthParameters { } impl CreateBotAuthParameters { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Builds the url with the provided data. #[must_use] pub fn build(self) -> String { diff --git a/src/builder/create_allowed_mentions.rs b/src/builder/create_allowed_mentions.rs index a059ccd71d3..7e75729b226 100644 --- a/src/builder/create_allowed_mentions.rs +++ b/src/builder/create_allowed_mentions.rs @@ -22,37 +22,35 @@ pub enum ParseValue { /// # /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); -/// # let b = CreateMessage::default(); +/// # let b = CreateMessage::new(); /// # let msg = ChannelId::new(7).message(&http, MessageId::new(8)).await?; /// use serenity::builder::{CreateAllowedMentions as Am, ParseValue}; /// /// // Mention only the user 110372470472613888 /// # let m = b.clone(); -/// m.allowed_mentions(Am::default().users(vec![110372470472613888])); +/// m.allowed_mentions(Am::new().users(vec![110372470472613888])); /// /// // Mention all users and the role 182894738100322304 /// # let m = b.clone(); -/// m.allowed_mentions(Am::default().parse(ParseValue::Users).roles(vec![182894738100322304])); +/// m.allowed_mentions(Am::new().parse(ParseValue::Users).roles(vec![182894738100322304])); /// /// // Mention all roles and nothing else /// # let m = b.clone(); -/// m.allowed_mentions(Am::default().parse(ParseValue::Roles)); +/// m.allowed_mentions(Am::new().parse(ParseValue::Roles)); /// /// // Mention all roles and users, but not everyone /// # let m = b.clone(); -/// m.allowed_mentions(Am::default().parse(ParseValue::Users).parse(ParseValue::Roles)); +/// m.allowed_mentions(Am::new().parse(ParseValue::Users).parse(ParseValue::Roles)); /// /// // Mention everyone and the users 182891574139682816, 110372470472613888 /// # let m = b.clone(); /// m.allowed_mentions( -/// Am::default() -/// .parse(ParseValue::Everyone) -/// .users(vec![182891574139682816, 110372470472613888]), +/// Am::new().parse(ParseValue::Everyone).users(vec![182891574139682816, 110372470472613888]), /// ); /// /// // Mention everyone and the message author. /// # let m = b.clone(); -/// m.allowed_mentions(Am::default().parse(ParseValue::Everyone).users(vec![msg.author.id])); +/// m.allowed_mentions(Am::new().parse(ParseValue::Everyone).users(vec![msg.author.id])); /// # Ok(()) /// # } /// ``` @@ -70,6 +68,11 @@ pub struct CreateAllowedMentions { } impl CreateAllowedMentions { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Add a value that's allowed to be mentioned. /// /// If passing in [`ParseValue::Users`] or [`ParseValue::Roles`], note that later calling diff --git a/src/builder/create_application_command_permission.rs b/src/builder/create_application_command_permission.rs index d56b5c29c61..19758773465 100644 --- a/src/builder/create_application_command_permission.rs +++ b/src/builder/create_application_command_permission.rs @@ -18,6 +18,11 @@ pub struct CreateApplicationCommandPermissionsData { } impl CreateApplicationCommandPermissionsData { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Create permissions for a guild application command. These will overwrite any existing /// permissions for that command. /// @@ -76,6 +81,11 @@ pub struct CreateApplicationCommandPermissionData { } impl CreateApplicationCommandPermissionData { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Sets the `CommandPermissionType` for the [`CommandPermissionData`]. /// /// [`CommandPermissionData`]: crate::model::application::command::CommandPermissionData diff --git a/src/builder/create_components.rs b/src/builder/create_components.rs index 73a28361e28..77addddc97e 100644 --- a/src/builder/create_components.rs +++ b/src/builder/create_components.rs @@ -9,6 +9,11 @@ use crate::model::channel::ReactionType; pub struct CreateComponents(pub Vec); impl CreateComponents { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Adds an action row. pub fn add_action_row(mut self, row: CreateActionRow) -> Self { self.0.push(row); @@ -62,6 +67,11 @@ impl Default for CreateActionRow { } impl CreateActionRow { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Adds a button. pub fn add_button(mut self, button: CreateButton) -> Self { self.components.push(ComponentBuilder::Button(button)); diff --git a/src/builder/create_embed.rs b/src/builder/create_embed.rs index 8af61beeeee..3c6fb282bb6 100644 --- a/src/builder/create_embed.rs +++ b/src/builder/create_embed.rs @@ -71,6 +71,11 @@ pub struct CreateEmbed { } impl CreateEmbed { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Set the author of the embed. /// /// Refer to the documentation for [`CreateEmbedAuthor`] for more information. @@ -180,8 +185,8 @@ impl CreateEmbed { /// if msg.content == "~embed" { /// let timestamp: Timestamp = /// "2004-06-08T16:04:23Z".parse().expect("Invalid timestamp!"); - /// let embed = CreateEmbed::default().title("hello").timestamp(timestamp); - /// let builder = CreateMessage::default().embed(embed); + /// let embed = CreateEmbed::new().title("hello").timestamp(timestamp); + /// let builder = CreateMessage::new().embed(embed); /// let _ = msg.channel_id.send_message(&context.http, builder).await; /// } /// } @@ -221,11 +226,11 @@ impl CreateEmbed { /// if let Some(channel) = channel_search { /// let icon_url = member.user.face(); /// let author = CreateEmbedAuthor::new(member.user.name).icon_url(icon_url); - /// let mut embed = CreateEmbed::default().title("Member Join").author(author); + /// let mut embed = CreateEmbed::new().title("Member Join").author(author); /// if let Some(joined_at) = member.joined_at { /// embed = embed.timestamp(joined_at); /// } - /// let builder = CreateMessage::default().embed(embed); + /// let builder = CreateMessage::new().embed(embed); /// let _ = channel.send_message(&context, builder).await; /// } /// } diff --git a/src/builder/create_interaction_response.rs b/src/builder/create_interaction_response.rs index a9dfea957b4..c0796ad5ce6 100644 --- a/src/builder/create_interaction_response.rs +++ b/src/builder/create_interaction_response.rs @@ -15,6 +15,11 @@ pub struct CreateInteractionResponse<'a> { } impl<'a> CreateInteractionResponse<'a> { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Creates a response to the interaction received. /// /// **Note**: Message contents must be under 2000 unicode code points, and embeds must be under @@ -113,6 +118,11 @@ pub struct CreateInteractionResponseData<'a> { } impl<'a> CreateInteractionResponseData<'a> { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Set whether the message is text-to-speech. /// /// Think carefully before setting this to `true`. @@ -233,7 +243,7 @@ impl<'a> CreateInteractionResponseData<'a> { } } -#[derive(Clone, Debug, Default, Serialize)] +#[derive(Clone, Debug, Serialize)] #[non_exhaustive] pub struct AutocompleteChoice { pub name: String, @@ -254,6 +264,11 @@ struct CreateAutocompleteResponseData { } impl CreateAutocompleteResponse { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Creates a response to an autocomplete interaction. /// /// # Errors diff --git a/src/builder/create_interaction_response_followup.rs b/src/builder/create_interaction_response_followup.rs index e1749ffb8f2..8b8703addae 100644 --- a/src/builder/create_interaction_response_followup.rs +++ b/src/builder/create_interaction_response_followup.rs @@ -29,6 +29,11 @@ pub struct CreateInteractionResponseFollowup<'a> { } impl<'a> CreateInteractionResponseFollowup<'a> { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Creates or edits a followup response to the response sent. If `message_id` is not `None`, /// then the corresponding message will be edited. Otherwise, a new message will be created. /// diff --git a/src/builder/create_invite.rs b/src/builder/create_invite.rs index f66f1922fd2..e796a2c468d 100644 --- a/src/builder/create_invite.rs +++ b/src/builder/create_invite.rs @@ -35,7 +35,7 @@ use crate::model::prelude::*; /// }, /// }; /// -/// let builder = CreateInvite::default().max_age(3600).max_uses(10); +/// let builder = CreateInvite::new().max_age(3600).max_uses(10); /// let creation = channel.create_invite(&context, builder).await; /// /// let invite = match creation { @@ -85,6 +85,11 @@ pub struct CreateInvite { } impl CreateInvite { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Creates an invite for the given channel. /// /// **Note**: Requires the [Create Instant Invite] permission. @@ -146,7 +151,7 @@ impl CreateInvite { /// # async fn example(context: &Context) -> CommandResult { /// # let channel = context.cache.guild_channel(81384788765712384).unwrap().clone(); /// # - /// let builder = CreateInvite::default().max_age(3600); + /// let builder = CreateInvite::new().max_age(3600); /// let invite = channel.create_invite(context, builder).await?; /// # Ok(()) /// # } @@ -179,7 +184,7 @@ impl CreateInvite { /// # async fn example(context: &Context) -> CommandResult { /// # let channel = context.cache.guild_channel(81384788765712384).unwrap().clone(); /// # - /// let builder = CreateInvite::default().max_uses(5); + /// let builder = CreateInvite::new().max_uses(5); /// let invite = channel.create_invite(context, builder).await?; /// # Ok(()) /// # } @@ -210,7 +215,7 @@ impl CreateInvite { /// # async fn example(context: &Context) -> CommandResult { /// # let channel = context.cache.guild_channel(81384788765712384).unwrap().clone(); /// # - /// let builder = CreateInvite::default().temporary(true); + /// let builder = CreateInvite::new().temporary(true); /// let invite = channel.create_invite(context, builder).await?; /// # Ok(()) /// # } @@ -243,7 +248,7 @@ impl CreateInvite { /// # async fn example(context: &Context) -> CommandResult { /// # let channel = context.cache.guild_channel(81384788765712384).unwrap().clone(); /// # - /// let builder = CreateInvite::default().unique(true); + /// let builder = CreateInvite::new().unique(true); /// let invite = channel.create_invite(context, builder).await?; /// # Ok(()) /// # } diff --git a/src/builder/create_message.rs b/src/builder/create_message.rs index 0d4f3807fcb..4b1ca38b0ad 100644 --- a/src/builder/create_message.rs +++ b/src/builder/create_message.rs @@ -36,8 +36,8 @@ use crate::model::prelude::*; /// /// let channel_id = ChannelId::new(7); /// -/// let embed = CreateEmbed::default().title("This is an embed").description("With a description"); -/// let builder = CreateMessage::default().content("test").tts(true).embed(embed); +/// let embed = CreateEmbed::new().title("This is an embed").description("With a description"); +/// let builder = CreateMessage::new().content("test").tts(true).embed(embed); /// let _ = channel_id.send_message(&http, builder).await; /// # } /// ``` @@ -70,6 +70,10 @@ pub struct CreateMessage<'a> { } impl<'a> CreateMessage<'a> { + pub fn new() -> Self { + Self::default() + } + /// Send a message to the channel. /// /// **Note**: Requires the [Send Messages] permission. Additionally, attaching files requires the diff --git a/src/builder/edit_automod_rule.rs b/src/builder/edit_automod_rule.rs index d5ccdb64371..86a2c44d97a 100644 --- a/src/builder/edit_automod_rule.rs +++ b/src/builder/edit_automod_rule.rs @@ -31,6 +31,11 @@ pub struct EditAutoModRule { } impl EditAutoModRule { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Creates or edits an automoderation [`Rule`] in a guild. Passing `Some(rule_id)` will edit /// that corresponding rule, otherwise a new rule will be created. /// @@ -51,6 +56,8 @@ impl EditAutoModRule { let http = http.as_ref(); match rule_id { Some(rule_id) => http.edit_automod_rule(guild_id.into(), rule_id.into(), &self).await, + // Automod Rule creation has required fields, whereas modifying a rule does not. + // TODO: Enforce these fields (maybe with a separate CreateAutoModRule builder). None => http.create_automod_rule(guild_id.into(), &self).await, } } diff --git a/src/builder/edit_channel.rs b/src/builder/edit_channel.rs index e633604aa90..3a48f77601b 100644 --- a/src/builder/edit_channel.rs +++ b/src/builder/edit_channel.rs @@ -18,7 +18,7 @@ use crate::model::prelude::*; /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); /// # let mut channel = ChannelId::new(1); -/// let builder = EditChannel::default().name("new name").topic("a test topic"); +/// let builder = EditChannel::new().name("new name").topic("a test topic"); /// if let Err(why) = channel.edit(&http, builder).await { /// // properly handle the error /// } @@ -53,6 +53,11 @@ pub struct EditChannel { } impl EditChannel { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the channel's settings. /// /// **Note**: Requires the [Manage Channels] permission. Modifying permissions via @@ -229,7 +234,7 @@ impl EditChannel { /// kind: PermissionOverwriteType::Member(UserId::new(1234)), /// }]; /// - /// let builder = EditChannel::default().name("my_edited_cool_channel").permissions(permissions); + /// let builder = EditChannel::new().name("my_edited_cool_channel").permissions(permissions); /// channel.edit(http, builder).await?; /// # Ok(()) /// # } diff --git a/src/builder/edit_guild.rs b/src/builder/edit_guild.rs index a04176f5b14..7d7fe7bbe8a 100644 --- a/src/builder/edit_guild.rs +++ b/src/builder/edit_guild.rs @@ -47,6 +47,11 @@ pub struct EditGuild { } impl EditGuild { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the given guild. /// /// **Note**: Requires the [Manage Guild] permission. @@ -107,7 +112,7 @@ impl EditGuild { /// let base64_icon = serenity::utils::read_image("./guild_icon.png")?; /// /// // assuming a `guild` has already been bound - /// let builder = EditGuild::default().icon(Some(base64_icon)); + /// let builder = EditGuild::new().icon(Some(base64_icon)); /// guild.edit(&http, builder).await?; /// # Ok(()) /// # } @@ -271,7 +276,7 @@ impl EditGuild { /// # let mut guild = GuildId::new(1).to_partial_guild(&http).await?; /// use serenity::model::guild::VerificationLevel; /// - /// let builder = EditGuild::default().verification_level(VerificationLevel::High); + /// let builder = EditGuild::new().verification_level(VerificationLevel::High); /// /// // assuming a `guild` has already been bound /// let edit = guild.edit(&http, builder).await; @@ -298,7 +303,7 @@ impl EditGuild { /// # let mut guild = GuildId::new(1).to_partial_guild(&http).await?; /// use serenity::model::guild::SystemChannelFlags; /// - /// let builder = EditGuild::default().system_channel_flags( + /// let builder = EditGuild::new().system_channel_flags( /// SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATIONS /// | SystemChannelFlags::SUPPRESS_GUILD_REMINDER_NOTIFICATIONS, /// ); diff --git a/src/builder/edit_guild_welcome_screen.rs b/src/builder/edit_guild_welcome_screen.rs index f7911beafc6..b9298365beb 100644 --- a/src/builder/edit_guild_welcome_screen.rs +++ b/src/builder/edit_guild_welcome_screen.rs @@ -19,6 +19,11 @@ pub struct EditGuildWelcomeScreen { } impl EditGuildWelcomeScreen { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the guild's welcome screen. /// /// **Note**: Requires the [Manage Guild] permission. diff --git a/src/builder/edit_guild_widget.rs b/src/builder/edit_guild_widget.rs index 05770a8785a..3a6ee4fadfe 100644 --- a/src/builder/edit_guild_widget.rs +++ b/src/builder/edit_guild_widget.rs @@ -17,6 +17,11 @@ pub struct EditGuildWidget { } impl EditGuildWidget { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the guild's widget. /// /// **Note**: Requires the [Manage Guild] permission. diff --git a/src/builder/edit_interaction_response.rs b/src/builder/edit_interaction_response.rs index eaa89b0dec4..feb9ab032fe 100644 --- a/src/builder/edit_interaction_response.rs +++ b/src/builder/edit_interaction_response.rs @@ -19,6 +19,11 @@ pub struct EditInteractionResponse { } impl EditInteractionResponse { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the initial interaction response. Does not work for ephemeral messages. /// /// The `application_id` used will usually be the bot's [`UserId`], except if the bot is very diff --git a/src/builder/edit_member.rs b/src/builder/edit_member.rs index 09b279da531..ee70b49eab2 100644 --- a/src/builder/edit_member.rs +++ b/src/builder/edit_member.rs @@ -24,6 +24,11 @@ pub struct EditMember { } impl EditMember { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the properties of the guild member. /// /// For details on permissions requirements, refer to each specific method. diff --git a/src/builder/edit_message.rs b/src/builder/edit_message.rs index 7e9d2b200ce..2d3fd8b55aa 100644 --- a/src/builder/edit_message.rs +++ b/src/builder/edit_message.rs @@ -23,7 +23,7 @@ use crate::model::prelude::*; /// # #[command] /// # async fn example(ctx: &Context) -> CommandResult { /// # let mut message = ChannelId::new(7).message(&ctx, MessageId::new(8)).await?; -/// let builder = EditMessage::default().content("hello"); +/// let builder = EditMessage::new().content("hello"); /// message.edit(ctx, builder).await?; /// # Ok(()) /// # } @@ -51,6 +51,11 @@ pub struct EditMessage<'a> { } impl<'a> EditMessage<'a> { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits a message in the channel. /// /// **Note**: Message contents must be under 2000 unicode code points, and embeds must be under diff --git a/src/builder/edit_profile.rs b/src/builder/edit_profile.rs index 9c1cd48a551..3c682306cd0 100644 --- a/src/builder/edit_profile.rs +++ b/src/builder/edit_profile.rs @@ -17,6 +17,11 @@ pub struct EditProfile { } impl EditProfile { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edit the current user's profile with the fields set. /// /// # Errors @@ -47,10 +52,8 @@ impl EditProfile { /// // assuming a `context` has been bound /// let mut user = context.cache.current_user().clone(); /// - /// let builder = EditProfile::default() - /// .avatar(&context, "./my_image.jpg") - /// .await - /// .expect("Failed to read image."); + /// let builder = + /// EditProfile::new().avatar(&context, "./my_image.jpg").await.expect("Failed to read image."); /// let _ = user.edit(&context, builder).await; /// # } /// # } diff --git a/src/builder/edit_role.rs b/src/builder/edit_role.rs index 48cada0fce2..e8483a658e5 100644 --- a/src/builder/edit_role.rs +++ b/src/builder/edit_role.rs @@ -35,7 +35,7 @@ use crate::utils::encode_image; /// # let guild_id = GuildId::new(2); /// # /// // assuming a `guild_id` has been bound -/// let builder = EditRole::default().name("a test role").hoist(true).mentionable(true); +/// let builder = EditRole::new().name("a test role").hoist(true).mentionable(true); /// let role = guild_id.create_role(&http, builder).await?; /// # Ok(()) /// # } @@ -63,6 +63,25 @@ pub struct EditRole { } impl EditRole { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + + /// Creates a new builder with the values of the given [`Role`]. + pub fn from_role(role: &Role) -> Self { + EditRole { + hoist: Some(role.hoist), + mentionable: Some(role.mentionable), + name: Some(role.name.clone()), + permissions: Some(role.permissions.bits()), + position: Some(role.position), + colour: Some(role.colour), + unicode_emoji: role.unicode_emoji.clone(), + icon: role.icon.clone(), + } + } + /// Edits the role. /// /// **Note**: Requires the [Manage Roles] permission. @@ -105,20 +124,6 @@ impl EditRole { Ok(role) } - /// Creates a new builder with the values of the given [`Role`]. - pub fn new(role: &Role) -> Self { - EditRole { - hoist: Some(role.hoist), - mentionable: Some(role.mentionable), - name: Some(role.name.clone()), - permissions: Some(role.permissions.bits()), - position: Some(role.position), - colour: Some(role.colour), - unicode_emoji: role.unicode_emoji.clone(), - icon: role.icon.clone(), - } - } - /// Set the colour of the role. pub fn colour(mut self, colour: impl Into) -> Self { self.colour = Some(colour.into()); diff --git a/src/builder/edit_scheduled_event.rs b/src/builder/edit_scheduled_event.rs index 0b459269a06..014004daeb2 100644 --- a/src/builder/edit_scheduled_event.rs +++ b/src/builder/edit_scheduled_event.rs @@ -30,6 +30,11 @@ pub struct EditScheduledEvent { } impl EditScheduledEvent { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Modifies a scheduled event in the guild with the data set, if any. /// /// **Note**: Requires the [Manage Events] permission. diff --git a/src/builder/edit_stage_instance.rs b/src/builder/edit_stage_instance.rs index 3453dd0ed99..be12c210bd8 100644 --- a/src/builder/edit_stage_instance.rs +++ b/src/builder/edit_stage_instance.rs @@ -14,6 +14,11 @@ pub struct EditStageInstance { } impl EditStageInstance { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the stage instance /// /// # Errors diff --git a/src/builder/edit_sticker.rs b/src/builder/edit_sticker.rs index c2dd1f9db4c..4bf9d532d11 100644 --- a/src/builder/edit_sticker.rs +++ b/src/builder/edit_sticker.rs @@ -31,6 +31,11 @@ pub struct EditSticker { } impl EditSticker { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the sticker. /// /// **Note**: Requires the [Manage Emojis and Stickers] permission. diff --git a/src/builder/edit_thread.rs b/src/builder/edit_thread.rs index a620b43ca58..b0730e99b0d 100644 --- a/src/builder/edit_thread.rs +++ b/src/builder/edit_thread.rs @@ -21,6 +21,11 @@ pub struct EditThread { } impl EditThread { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the thread. /// /// # Errors diff --git a/src/builder/edit_voice_state.rs b/src/builder/edit_voice_state.rs index 92a8f11c5a4..389178301af 100644 --- a/src/builder/edit_voice_state.rs +++ b/src/builder/edit_voice_state.rs @@ -17,6 +17,11 @@ pub struct EditVoiceState { } impl EditVoiceState { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the given user's voice state in a stage channel. Pass [`None`] for `user_id` to edit /// the current user's voice state. /// diff --git a/src/builder/edit_webhook.rs b/src/builder/edit_webhook.rs index 205ade0a72f..3181e8ee20a 100644 --- a/src/builder/edit_webhook.rs +++ b/src/builder/edit_webhook.rs @@ -16,6 +16,11 @@ pub struct EditWebhook { } impl EditWebhook { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the webhook corresponding to the provided Id and token, and returns the resulting ne /// [`Webhook`]. /// diff --git a/src/builder/edit_webhook_message.rs b/src/builder/edit_webhook_message.rs index d4f4dba3310..ac44380b67c 100644 --- a/src/builder/edit_webhook_message.rs +++ b/src/builder/edit_webhook_message.rs @@ -23,6 +23,11 @@ pub struct EditWebhookMessage { } impl EditWebhookMessage { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Edits the webhook's message. /// /// **Note**: Message contents must be under 2000 unicode code points, and embeds must be under diff --git a/src/builder/execute_webhook.rs b/src/builder/execute_webhook.rs index 26eb31856d4..7e91ac38e2d 100644 --- a/src/builder/execute_webhook.rs +++ b/src/builder/execute_webhook.rs @@ -24,19 +24,19 @@ use crate::model::prelude::*; /// let url = "https://discord.com/api/webhooks/245037420704169985/ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// let webhook = Webhook::from_url(&http, url).await?; /// -/// let website = CreateEmbed::default() +/// let website = CreateEmbed::new() /// .title("The Rust Language Website") /// .description("Rust is a systems programming language.") /// .colour(Colour::from_rgb(222, 165, 132)); /// -/// let resources = CreateEmbed::default() +/// let resources = CreateEmbed::new() /// .title("Rust Resources") /// .description("A few resources to help with learning Rust") /// .colour(0xDEA584) /// .field("The Rust Book", "A comprehensive resource for Rust.", false) /// .field("Rust by Example", "A collection of Rust examples", false); /// -/// let builder = ExecuteWebhook::default() +/// let builder = ExecuteWebhook::new() /// .content("Here's some information on Rust:") /// .embeds(vec![website, resources]); /// webhook.execute(&http, false, builder).await?; @@ -68,6 +68,11 @@ pub struct ExecuteWebhook<'a> { } impl<'a> ExecuteWebhook<'a> { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Executes the webhook with the given content. /// /// If `wait` is set to false, this function will return `Ok(None)` on success. Otherwise, @@ -136,7 +141,7 @@ impl<'a> ExecuteWebhook<'a> { /// # let http = Http::new("token"); /// # let webhook = Webhook::from_id_with_token(&http, 0, "").await?; /// # - /// let builder = ExecuteWebhook::default() + /// let builder = ExecuteWebhook::new() /// .avatar_url("https://i.imgur.com/KTs6whd.jpg") /// .content("Here's a webhook"); /// webhook.execute(&http, false, builder).await?; @@ -166,7 +171,7 @@ impl<'a> ExecuteWebhook<'a> { /// # let http = Http::new("token"); /// # let webhook = Webhook::from_id_with_token(&http, 0, "").await?; /// # - /// let builder = ExecuteWebhook::default().content("foo"); + /// let builder = ExecuteWebhook::new().content("foo"); /// let execution = webhook.execute(&http, false, builder).await; /// /// if let Err(why) = execution { @@ -199,7 +204,7 @@ impl<'a> ExecuteWebhook<'a> { /// let url = "https://discord.com/api/webhooks/245037420704169985/ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// let mut webhook = Webhook::from_url(&http, url).await?; /// - /// let builder = ExecuteWebhook::default().in_thread(12345678).content("test"); + /// let builder = ExecuteWebhook::new().in_thread(12345678).content("test"); /// webhook.execute(&http, false, builder).await?; /// # Ok(()) /// # } @@ -283,7 +288,7 @@ impl<'a> ExecuteWebhook<'a> { /// # let http = Http::new("token"); /// # let webhook = Webhook::from_id_with_token(&http, 0, "").await?; /// # - /// let builder = ExecuteWebhook::default().content("hello").tts(true); + /// let builder = ExecuteWebhook::new().content("hello").tts(true); /// let execution = webhook.execute(&http, false, builder).await; /// /// if let Err(why) = execution { @@ -312,7 +317,7 @@ impl<'a> ExecuteWebhook<'a> { /// # let http = Http::new("token"); /// # let webhook = Webhook::from_id_with_token(&http, 0, "").await?; /// # - /// let builder = ExecuteWebhook::default().content("hello").username("hakase"); + /// let builder = ExecuteWebhook::new().content("hello").username("hakase"); /// let execution = webhook.execute(&http, false, builder).await; /// /// if let Err(why) = execution { @@ -342,7 +347,7 @@ impl<'a> ExecuteWebhook<'a> { /// # let http = Http::new("token"); /// # let webhook = Webhook::from_id_with_token(&http, 0, "").await?; /// # - /// let builder = ExecuteWebhook::default() + /// let builder = ExecuteWebhook::new() /// .content("https://docs.rs/serenity/latest/serenity/") /// .flags(MessageFlags::SUPPRESS_EMBEDS); /// let execution = webhook.execute(&http, false, builder).await; diff --git a/src/builder/get_messages.rs b/src/builder/get_messages.rs index 9ecde79e0a8..7c156114ee2 100644 --- a/src/builder/get_messages.rs +++ b/src/builder/get_messages.rs @@ -40,7 +40,7 @@ use crate::model::prelude::*; /// // you can then pass it into a function which retrieves messages: /// let channel_id = ChannelId::new(81384788765712384); /// -/// let builder = GetMessages::default().after(MessageId::new(158339864557912064)).limit(25); +/// let builder = GetMessages::new().after(MessageId::new(158339864557912064)).limit(25); /// let _messages = channel_id.messages(&http, builder).await?; /// # Ok(()) /// # } @@ -53,6 +53,11 @@ pub struct GetMessages { } impl GetMessages { + /// Equivalent to [`Self::default`]. + pub fn new() -> Self { + Self::default() + } + /// Gets messages from the channel. /// /// **Note**: If the user does not have the [Read Message History] permission, returns an empty diff --git a/src/framework/standard/help_commands.rs b/src/framework/standard/help_commands.rs index 5f473fde8ff..6146e38f446 100644 --- a/src/framework/standard/help_commands.rs +++ b/src/framework/standard/help_commands.rs @@ -1022,7 +1022,7 @@ async fn send_grouped_commands_embed( // creating embed outside message builder since flatten_group_to_string // may return an error. - let mut embed = CreateEmbed::default().colour(colour).description(help_description); + let mut embed = CreateEmbed::new().colour(colour).description(help_description); for group in groups { let mut embed_text = String::default(); @@ -1031,7 +1031,7 @@ async fn send_grouped_commands_embed( embed = embed.field(group.name, &embed_text, true); } - let builder = CreateMessage::default().embed(embed); + let builder = CreateMessage::new().embed(embed); channel_id.send_message(cache_http, builder).await } @@ -1044,7 +1044,7 @@ async fn send_single_command_embed( command: &Command<'_>, colour: Colour, ) -> Result { - let mut embed = CreateEmbed::default().title(command.name).colour(colour); + let mut embed = CreateEmbed::new().title(command.name).colour(colour); if let Some(desc) = command.description { embed = embed.description(desc); @@ -1102,7 +1102,7 @@ async fn send_single_command_embed( ); } - let builder = CreateMessage::default().embed(embed); + let builder = CreateMessage::new().embed(embed); channel_id.send_message(cache_http, builder).await } @@ -1117,8 +1117,8 @@ async fn send_suggestion_embed( ) -> Result { let text = help_description.replace("{}", &suggestions.join("`, `")); - let embed = CreateEmbed::default().colour(colour).description(text); - let builder = CreateMessage::default().embed(embed); + let embed = CreateEmbed::new().colour(colour).description(text); + let builder = CreateMessage::new().embed(embed); channel_id.send_message(cache_http, builder).await } @@ -1130,8 +1130,8 @@ async fn send_error_embed( input: &str, colour: Colour, ) -> Result { - let embed = CreateEmbed::default().colour(colour).description(input); - let builder = CreateMessage::default().embed(embed); + let embed = CreateEmbed::new().colour(colour).description(input); + let builder = CreateMessage::new().embed(embed); channel_id.send_message(cache_http, builder).await } diff --git a/src/model/application/interaction/application_command.rs b/src/model/application/interaction/application_command.rs index 782f1346b21..3e151eee7ee 100644 --- a/src/model/application/interaction/application_command.rs +++ b/src/model/application/interaction/application_command.rs @@ -213,7 +213,7 @@ impl ApplicationCommandInteraction { /// Returns an [`Error::Http`] if the API returns an error, or an [`Error::Json`] if there is /// an error in deserializing the API response. pub async fn defer(&self, http: impl AsRef) -> Result<()> { - let builder = CreateInteractionResponse::default() + let builder = CreateInteractionResponse::new() .kind(InteractionResponseType::DeferredChannelMessageWithSource); self.create_interaction_response(http, builder).await } diff --git a/src/model/application/interaction/message_component.rs b/src/model/application/interaction/message_component.rs index ed70c15fc85..e7ab63a5a8e 100644 --- a/src/model/application/interaction/message_component.rs +++ b/src/model/application/interaction/message_component.rs @@ -187,8 +187,8 @@ impl MessageComponentInteraction { /// Returns an [`Error::Http`] if the API returns an error, or an [`Error::Json`] if there is /// an error in deserializing the API response. pub async fn defer(&self, http: impl AsRef) -> Result<()> { - let builder = CreateInteractionResponse::default() - .kind(InteractionResponseType::DeferredUpdateMessage); + let builder = + CreateInteractionResponse::new().kind(InteractionResponseType::DeferredUpdateMessage); self.create_interaction_response(http, builder).await } } diff --git a/src/model/application/interaction/modal.rs b/src/model/application/interaction/modal.rs index 783d507cbec..02f056a50a3 100644 --- a/src/model/application/interaction/modal.rs +++ b/src/model/application/interaction/modal.rs @@ -175,8 +175,8 @@ impl ModalSubmitInteraction { /// Returns an [`Error::Http`] if the API returns an error, or an [`Error::Json`] if there is /// an error in deserializing the API response. pub async fn defer(&self, http: impl AsRef) -> Result<()> { - let builder = CreateInteractionResponse::default() - .kind(InteractionResponseType::DeferredUpdateMessage); + let builder = + CreateInteractionResponse::new().kind(InteractionResponseType::DeferredUpdateMessage); self.create_interaction_response(http, builder).await } } diff --git a/src/model/channel/channel_category.rs b/src/model/channel/channel_category.rs index 9e8f49efdc9..2dd94cd003e 100644 --- a/src/model/channel/channel_category.rs +++ b/src/model/channel/channel_category.rs @@ -105,7 +105,7 @@ impl ChannelCategory { /// # async fn run() { /// # let http = Http::new("token"); /// # let category = ChannelId::new(1234); - /// let builder = EditChannel::default().name("test"); + /// let builder = EditChannel::new().name("test"); /// category.edit(&http, builder).await; /// # } /// ``` diff --git a/src/model/channel/channel_id.rs b/src/model/channel/channel_id.rs index fcb8459eb02..954b3848778 100644 --- a/src/model/channel/channel_id.rs +++ b/src/model/channel/channel_id.rs @@ -310,7 +310,7 @@ impl ChannelId { /// # async fn run() { /// # let http = Http::new("token"); /// # let channel_id = ChannelId::new(1234); - /// let builder = EditChannel::default().name("test").bitrate(64000); + /// let builder = EditChannel::new().name("test").bitrate(64000); /// channel_id.edit(&http, builder).await; /// # } /// ``` @@ -630,7 +630,7 @@ impl ChannelId { cache_http: impl CacheHttp, content: impl Into, ) -> Result { - let builder = CreateMessage::default().content(content); + let builder = CreateMessage::new().content(content); self.send_message(cache_http, builder).await } @@ -658,7 +658,7 @@ impl ChannelId { /// /// let paths = vec!["/path/to/file.jpg", "path/to/file2.jpg"]; /// - /// let builder = CreateMessage::default().content("some files"); + /// let builder = CreateMessage::new().content("some files"); /// let _ = channel_id.send_files(&http, paths, builder).await; /// # } /// ``` @@ -682,7 +682,7 @@ impl ChannelId { /// /// let files = vec![(&f1, "my_file.jpg"), (&f2, "my_file2.jpg")]; /// - /// let builder = CreateMessage::default().content("some files"); + /// let builder = CreateMessage::new().content("some files"); /// let _ = channel_id.send_files(&http, files, builder).await; /// # Ok(()) /// # } @@ -1120,7 +1120,7 @@ impl> MessagesIter { // If `self.before` is not set yet, we can use `.messages` to fetch // the last message after very first fetch from last. - let mut builder = GetMessages::default().limit(grab_size); + let mut builder = GetMessages::new().limit(grab_size); if let Some(before) = self.before { builder = builder.before(before); } diff --git a/src/model/channel/guild_channel.rs b/src/model/channel/guild_channel.rs index ca8ca076887..b089ab3027d 100644 --- a/src/model/channel/guild_channel.rs +++ b/src/model/channel/guild_channel.rs @@ -399,7 +399,7 @@ impl GuildChannel { /// # async fn run() { /// # let http = Http::new("token"); /// # let channel = ChannelId::new(1234); - /// let builder = EditChannel::default().name("test").bitrate(86400); + /// let builder = EditChannel::new().name("test").bitrate(86400); /// channel.edit(&http, builder).await; /// # } /// ``` @@ -483,7 +483,7 @@ impl GuildChannel { /// // assuming the cache has been unlocked /// let channel = cache.guild_channel(channel_id).ok_or(ModelError::ItemMissing)?; /// - /// let builder = EditVoiceState::default().suppress(false); + /// let builder = EditVoiceState::new().suppress(false); /// channel.edit_voice_state(&http, user_id, builder).await?; /// # Ok(()) /// # } @@ -533,7 +533,7 @@ impl GuildChannel { /// let channel = cache.guild_channel(channel_id).ok_or(ModelError::ItemMissing)?; /// /// // Send a request to speak - /// let builder = EditVoiceState::default().request_to_speak(true); + /// let builder = EditVoiceState::new().request_to_speak(true); /// channel.edit_own_voice_state(&http, builder.clone()).await?; /// /// // Clear own request to speak @@ -728,7 +728,7 @@ impl GuildChannel { /// }, /// }; /// - /// let builder = CreateMessage::default().content("here's a cat"); + /// let builder = CreateMessage::new().content("here's a cat"); /// let _ = msg /// .channel_id /// .send_files(&context.http, vec![(&file, "cat.png")], builder) diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs index 0396e116995..76f6c0644de 100644 --- a/src/model/channel/message.rs +++ b/src/model/channel/message.rs @@ -313,7 +313,7 @@ impl Message { /// # let http = Http::new("token"); /// # let mut message = ChannelId::new(7).message(&http, MessageId::new(8)).await?; /// // assuming a `message` has already been bound - /// let builder = EditMessage::default().content("new content"); + /// let builder = EditMessage::new().content("new content"); /// message.edit(&http, builder).await?; /// # Ok(()) /// # } @@ -659,9 +659,9 @@ impl Message { } } - let mut builder = CreateMessage::default().content(content); + let mut builder = CreateMessage::new().content(content); if let Some(ping_user) = inlined { - let allowed_mentions = CreateAllowedMentions::default() + let allowed_mentions = CreateAllowedMentions::new() .replied_user(ping_user) // By providing allowed_mentions, Discord disabled _all_ pings by default so we // need to re-enable them diff --git a/src/model/guild/guild_id.rs b/src/model/guild/guild_id.rs index 02cbaa57d7f..9dc944f1c8a 100644 --- a/src/model/guild/guild_id.rs +++ b/src/model/guild/guild_id.rs @@ -90,7 +90,7 @@ impl GuildId { /// # async fn run() { /// # use serenity::http::Http; /// # let http = Http::new("token"); - /// let builder = EditAutoModRule::default() + /// let builder = EditAutoModRule::new() /// .name("foobar filter") /// .trigger(Trigger::Keyword(vec!["foo*".to_string(), "*bar".to_string()])) /// .actions(vec![Action::BlockMessage, Action::Timeout(Duration::from_secs(60))]); @@ -628,7 +628,7 @@ impl GuildId { /// # let http = Http::new("token"); /// # let role_id = RoleId::new(7); /// # let user_id = UserId::new(7); - /// let builder = EditMember::default().mute(true).roles(vec![role_id]); + /// let builder = EditMember::new().mute(true).roles(vec![role_id]); /// let _ = GuildId::new(7).edit_member(&http, user_id, builder).await?; /// # Ok(()) /// # } @@ -687,7 +687,7 @@ impl GuildId { /// # let role_id = RoleId::new(8); /// # /// // assuming a `role_id` and `guild_id` has been bound - /// let builder = EditRole::default().name("a test role").hoist(true); + /// let builder = EditRole::new().name("a test role").hoist(true); /// let role = guild_id.edit_role(&http, role_id, builder).await?; /// # Ok(()) /// # } @@ -743,7 +743,7 @@ impl GuildId { /// /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); - /// let builder = EditSticker::default().name("Bun bun meow"); + /// let builder = EditSticker::new().name("Bun bun meow"); /// let _ = GuildId::new(7).edit_sticker(&http, StickerId::new(7), builder).await?; /// # Ok(()) /// # } @@ -1083,7 +1083,7 @@ impl GuildId { user_id: impl Into, channel_id: impl Into, ) -> Result { - let builder = EditMember::default().voice_channel(channel_id.into()); + let builder = EditMember::new().voice_channel(channel_id.into()); self.edit_member(http, user_id, builder).await } @@ -1110,7 +1110,7 @@ impl GuildId { http: impl AsRef, user_id: impl Into, ) -> Result { - self.edit_member(http, user_id, EditMember::default().disconnect_member()).await + self.edit_member(http, user_id, EditMember::new().disconnect_member()).await } /// Gets the number of [`Member`]s that would be pruned with the given diff --git a/src/model/guild/member.rs b/src/model/guild/member.rs index 53785063a55..2ad4d3221f6 100644 --- a/src/model/guild/member.rs +++ b/src/model/guild/member.rs @@ -131,7 +131,7 @@ impl Member { let mut target_roles = self.roles.clone(); target_roles.extend_from_slice(role_ids); - let builder = EditMember::default().roles(target_roles); + let builder = EditMember::new().roles(target_roles); self.edit(http, builder).await } @@ -224,7 +224,7 @@ impl Member { http: impl AsRef, time: Timestamp, ) -> Result<()> { - let builder = EditMember::default().disable_communication_until_datetime(time); + let builder = EditMember::new().disable_communication_until_datetime(time); match self.guild_id.edit_member(http, self.user.id, builder).await { Ok(_) => { self.communication_disabled_until = Some(time); @@ -277,7 +277,7 @@ impl Member { /// [Moderate Members]: Permissions::MODERATE_MEMBERS #[doc(alias = "timeout")] pub async fn enable_communication(&mut self, http: impl AsRef) -> Result<()> { - let builder = EditMember::default().enable_communication(); + let builder = EditMember::new().enable_communication(); *self = self.guild_id.edit_member(http, self.user.id, builder).await?; Ok(()) } @@ -499,7 +499,7 @@ impl Member { let mut target_roles = self.roles.clone(); target_roles.retain(|r| !role_ids.contains(r)); - let builder = EditMember::default().roles(target_roles); + let builder = EditMember::new().roles(target_roles); self.edit(http, builder).await } diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index cf3d87d461e..16a8030bc10 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -1049,7 +1049,7 @@ impl Guild { /// let base64_icon = serenity::utils::read_image("./icon.png")?; /// /// // assuming a `guild` has already been bound - /// let builder = EditGuild::default().icon(Some(base64_icon)); + /// let builder = EditGuild::new().icon(Some(base64_icon)); /// guild.edit(&http, builder).await?; /// # Ok(()) /// # } @@ -1247,7 +1247,7 @@ impl Guild { /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); /// # let guild = Guild::get(&http, GuildId::new(7)).await?; - /// let builder = EditSticker::default().name("Bun bun meow"); + /// let builder = EditSticker::new().name("Bun bun meow"); /// guild.edit_sticker(&http, StickerId::new(7), builder).await?; /// # Ok(()) /// # } diff --git a/src/model/guild/partial_guild.rs b/src/model/guild/partial_guild.rs index 412704e3810..9f150126518 100644 --- a/src/model/guild/partial_guild.rs +++ b/src/model/guild/partial_guild.rs @@ -866,7 +866,7 @@ impl PartialGuild { /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); /// # let guild = PartialGuild::get(&http, GuildId::new(7)).await?; - /// let builder = EditSticker::default().name("Bun bun meow"); + /// let builder = EditSticker::new().name("Bun bun meow"); /// guild.edit_sticker(&http, StickerId::new(7), builder).await?; /// # Ok(()) /// # } diff --git a/src/model/mention.rs b/src/model/mention.rs index e4710f03854..ab11cef975f 100644 --- a/src/model/mention.rs +++ b/src/model/mention.rs @@ -36,7 +36,7 @@ pub trait Mentionable { /// to_channel: GuildChannel, /// rules_channel: ChannelId, /// ) -> Result<(), Error> { - /// let builder = CreateMessage::default().content(format!( + /// let builder = CreateMessage::new().content(format!( /// "Hi {member}, welcome to the server! \ /// Please refer to {rules} for our code of conduct, \ /// and enjoy your stay.", diff --git a/src/model/sticker/mod.rs b/src/model/sticker/mod.rs index 9f12571cd22..a295146cc1c 100644 --- a/src/model/sticker/mod.rs +++ b/src/model/sticker/mod.rs @@ -94,7 +94,7 @@ impl Sticker { /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); /// # let mut sticker = GuildId::new(7).sticker(&http, StickerId::new(7)).await?; - /// let builder = EditSticker::default().name("Bun bun meow"); + /// let builder = EditSticker::new().name("Bun bun meow"); /// sticker.edit(&http, builder).await?; /// # Ok(()) /// # } diff --git a/src/model/user.rs b/src/model/user.rs index 223603e660d..eb614fb65bb 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -239,7 +239,7 @@ impl CurrentUser { /// # async fn run() -> Result<(), Box> { /// # let http = Http::new("token"); /// # let mut user = CurrentUser::default(); - /// let builder = EditProfile::default().avatar(&http, "./avatar.png").await?; + /// let builder = EditProfile::new().avatar(&http, "./avatar.png").await?; /// user.edit(&http, builder).await; /// # Ok(()) /// # } @@ -453,7 +453,7 @@ impl CurrentUser { permissions: Permissions, scopes: &[Scope], ) -> Result { - let builder = CreateBotAuthParameters::default() + let builder = CreateBotAuthParameters::new() .permissions(permissions) .scopes(scopes) .auto_client_id(http) @@ -810,7 +810,7 @@ impl User { /// /// let help = format!("Helpful info here. Invite me with this link: <{}>", url); /// - /// let builder = CreateMessage::default().content(help); + /// let builder = CreateMessage::new().content(help); /// let dm = msg.author.direct_message(&ctx, builder).await; /// /// match dm { diff --git a/src/model/webhook.rs b/src/model/webhook.rs index 6a0d4069069..9c7793bab88 100644 --- a/src/model/webhook.rs +++ b/src/model/webhook.rs @@ -226,7 +226,7 @@ impl Webhook { /// let url = "https://discord.com/api/webhooks/245037420704169985/ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// let mut webhook = Webhook::from_url(&http, url).await?; /// - /// let builder = EditWebhook::default().name("new name"); + /// let builder = EditWebhook::new().name("new name"); /// webhook.edit(&http, builder).await?; /// # Ok(()) /// # } @@ -261,7 +261,7 @@ impl Webhook { /// let url = "https://discord.com/api/webhooks/245037420704169985/ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// let mut webhook = Webhook::from_url(&http, url).await?; /// - /// let builder = ExecuteWebhook::default().content("test"); + /// let builder = ExecuteWebhook::new().content("test"); /// webhook.execute(&http, false, builder).await?; /// # Ok(()) /// # } @@ -281,7 +281,7 @@ impl Webhook { /// let url = "https://discord.com/api/webhooks/245037420704169985/ig5AO-wdVWpCBtUUMxmgsWryqgsW3DChbKYOINftJ4DCrUbnkedoYZD0VOH1QLr-S3sV"; /// let mut webhook = Webhook::from_url(&http, url).await?; /// - /// let embed = CreateEmbed::default() + /// let embed = CreateEmbed::new() /// .title("Rust's website") /// .description( /// "Rust is a systems programming language that runs blazingly fast, prevents \ @@ -289,7 +289,7 @@ impl Webhook { /// ) /// .url("https://rust-lang.org"); /// - /// let builder = ExecuteWebhook::default().content("test").username("serenity").embed(embed); + /// let builder = ExecuteWebhook::new().content("test").username("serenity").embed(embed); /// webhook.execute(&http, false, builder).await?; /// # Ok(()) /// # }