From f9f00dfc599f0a52a3321bef756a3b3a8aad36d3 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Tue, 26 Sep 2023 16:02:32 -0400 Subject: [PATCH 01/21] add initial entitlement structure --- twilight-model/src/application/mod.rs | 1 + .../application/monetization/entitlement.rs | 109 ++++++++++++++++++ .../monetization/entitlement_type.rs | 58 ++++++++++ .../src/application/monetization/mod.rs | 4 + twilight-model/src/id/marker.rs | 18 +++ 5 files changed, 190 insertions(+) create mode 100644 twilight-model/src/application/monetization/entitlement.rs create mode 100644 twilight-model/src/application/monetization/entitlement_type.rs create mode 100644 twilight-model/src/application/monetization/mod.rs diff --git a/twilight-model/src/application/mod.rs b/twilight-model/src/application/mod.rs index c87d55ae72c..c327b956239 100644 --- a/twilight-model/src/application/mod.rs +++ b/twilight-model/src/application/mod.rs @@ -1,2 +1,3 @@ pub mod command; pub mod interaction; +pub mod monetization; diff --git a/twilight-model/src/application/monetization/entitlement.rs b/twilight-model/src/application/monetization/entitlement.rs new file mode 100644 index 00000000000..cc4b8c5c0b1 --- /dev/null +++ b/twilight-model/src/application/monetization/entitlement.rs @@ -0,0 +1,109 @@ +use serde::{Deserialize, Serialize}; + +use crate::{ + id::{ + marker::{ + ApplicationMarker, EntitlementMarker, EntitlementSkuMarker, GuildMarker, UserMarker, + }, + Id, + }, + util::Timestamp, +}; + +use super::entitlement_type::EntitlementType; + +/// Entitlements in Discord represent that a user or guild has access to a premium offering in your application. +#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] +pub struct Entitlement { + /// ID of the parent application. + application_id: Id, + /// Not applicable for App Subscriptions. Subscriptions are not consumed and will be `false` + consumed: bool, + /// Date at which the entitlement is no longer valid. Not present when using test entitlements. + ends_at: Option, + /// ID of the guild that is granted access to the entitlement's sku. + guild_id: Option>, + /// ID of the entitlement. + id: Id, + /// Type of entitlement. + #[serde(rename = "type")] + kind: EntitlementType, + /// ID of the SKU. + sku_id: Id, + /// Start date at which the entitlement is valid. Not present when using test entitlements. + starts_at: Option, + /// ID of the user that is granted access to the entitlement's sku. + user_id: Option>, +} + +#[cfg(test)] +mod tests { + use std::error::Error; + + use serde_test::Token; + + use super::Entitlement; + use crate::application::monetization::entitlement_type::EntitlementType; + use crate::id::Id; + use crate::util::Timestamp; + + #[test] + fn entitlement() -> Result<(), Box> { + let starts_at_str = "2022-09-14T17:00:18.704163+00:00"; + let ends_at_str = "2022-10-14T17:00:21.704163+00:00"; + let starts_at = Timestamp::parse(starts_at_str)?; + let ends_at = Timestamp::parse(ends_at_str)?; + + let value = Entitlement { + application_id: Id::new(1), + consumed: false, + ends_at: ends_at.into(), + guild_id: Some(Id::new(10)), + id: Id::new(2), + kind: EntitlementType::ApplicationSubscription, + sku_id: Id::new(3), + starts_at: starts_at.into(), + user_id: Some(Id::new(42)), + }; + + serde_test::assert_tokens( + &value, + &[ + Token::Struct { + name: "Entitlement", + len: 9, + }, + Token::Str("application_id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("1"), + Token::Str("consumed"), + Token::Bool(false), + Token::Str("ends_at"), + Token::Some, + Token::Str(ends_at_str), + Token::Str("guild_id"), + Token::Some, + Token::NewtypeStruct { name: "Id" }, + Token::Str("10"), + Token::Str("id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("2"), + Token::Str("type"), + Token::U8(8), + Token::Str("sku_id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("3"), + Token::Str("starts_at"), + Token::Some, + Token::Str(starts_at_str), + Token::Str("user_id"), + Token::Some, + Token::NewtypeStruct { name: "Id" }, + Token::Str("42"), + Token::StructEnd, + ], + ); + + Ok(()) + } +} diff --git a/twilight-model/src/application/monetization/entitlement_type.rs b/twilight-model/src/application/monetization/entitlement_type.rs new file mode 100644 index 00000000000..c6f77337600 --- /dev/null +++ b/twilight-model/src/application/monetization/entitlement_type.rs @@ -0,0 +1,58 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[non_exhaustive] +#[serde(from = "u8", into = "u8")] +pub enum EntitlementType { + /// Entitlement was purchased as an app subscription. + ApplicationSubscription, + Unknown(u8), +} + +impl From for EntitlementType { + fn from(value: u8) -> Self { + match value { + 8 => Self::ApplicationSubscription, + other => Self::Unknown(other), + } + } +} + +impl From for u8 { + fn from(value: EntitlementType) -> Self { + match value { + EntitlementType::ApplicationSubscription => 8, + EntitlementType::Unknown(other) => other, + } + } +} + +impl EntitlementType { + pub const fn name(self) -> &'static str { + match self { + Self::ApplicationSubscription => "ApplicationSubscription", + Self::Unknown(_) => "Unknown", + } + } +} + +#[cfg(test)] +mod tests { + use super::EntitlementType; + use serde_test::Token; + + #[test] + fn variants() { + serde_test::assert_tokens(&EntitlementType::ApplicationSubscription, &[Token::U8(8)]); + serde_test::assert_tokens(&EntitlementType::Unknown(99), &[Token::U8(99)]); + } + + #[test] + fn names() { + assert_eq!( + EntitlementType::ApplicationSubscription.name(), + "ApplicationSubscription" + ); + assert_eq!(EntitlementType::Unknown(99).name(), "Unknown"); + } +} diff --git a/twilight-model/src/application/monetization/mod.rs b/twilight-model/src/application/monetization/mod.rs new file mode 100644 index 00000000000..eb4caf25db7 --- /dev/null +++ b/twilight-model/src/application/monetization/mod.rs @@ -0,0 +1,4 @@ +pub mod entitlement; +pub mod entitlement_type; + +pub use self::{entitlement::Entitlement, entitlement_type::EntitlementType}; diff --git a/twilight-model/src/id/marker.rs b/twilight-model/src/id/marker.rs index 9b333908394..cf6cc56de3b 100644 --- a/twilight-model/src/id/marker.rs +++ b/twilight-model/src/id/marker.rs @@ -85,6 +85,24 @@ pub struct CommandVersionMarker; #[non_exhaustive] pub struct EmojiMarker; +/// Marker for entitlement IDs. +/// +/// Types such as [`Entitlement`] use this ID marker. +/// +/// [`Entitlement`]: crate::application::monetization::entitlement::Entitlement +#[derive(Debug)] +#[non_exhaustive] +pub struct EntitlementMarker; + +/// Marker for entitlement SKU IDs. +/// +/// Types such as [`Entitlement`] use this ID marker. +/// +/// [`Entitlement`]: crate::application::monetization::entitlement::Entitlement +#[derive(Debug)] +#[non_exhaustive] +pub struct EntitlementSkuMarker; + /// Marker for generic IDs. /// /// Types such as [`AuditLogChange::Id`] or [`CommandOptionValue`] use this From 8053319da2901697c750fb16eb34f890693855de Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Tue, 26 Sep 2023 17:10:03 -0400 Subject: [PATCH 02/21] start implementing request structure --- twilight-http/src/request/application/mod.rs | 1 + .../monetization/get_entitlements.rs | 105 ++++++++++++++++++ .../request/application/monetization/mod.rs | 1 + twilight-model/src/id/mod.rs | 36 +++++- twilight-validate/src/request.rs | 42 +++++++ 5 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 twilight-http/src/request/application/monetization/get_entitlements.rs create mode 100644 twilight-http/src/request/application/monetization/mod.rs diff --git a/twilight-http/src/request/application/mod.rs b/twilight-http/src/request/application/mod.rs index c87d55ae72c..c327b956239 100644 --- a/twilight-http/src/request/application/mod.rs +++ b/twilight-http/src/request/application/mod.rs @@ -1,2 +1,3 @@ pub mod command; pub mod interaction; +pub mod monetization; diff --git a/twilight-http/src/request/application/monetization/get_entitlements.rs b/twilight-http/src/request/application/monetization/get_entitlements.rs new file mode 100644 index 00000000000..4d641d9f4ca --- /dev/null +++ b/twilight-http/src/request/application/monetization/get_entitlements.rs @@ -0,0 +1,105 @@ +use twilight_model::id::marker::{ + EntitlementMarker, EntitlementSkuMarker, GuildMarker, UserMarker, +}; + +use crate::Client; + +use twilight_validate::request::{ + get_entitlements_limit as validate_get_entitlements_limit, ValidationError, +}; + +struct GetEntitlementsFields<'a> { + after: Option, + before: Option, + exclude_ended: Option, + guild_id: Option, + limit: Option, + sku_ids: Option<&'a [EntitlementSkuMarker]>, + user_id: Option, +} + +/// Get all entitlements for a given app, active and expired. +#[must_use = "requests must be configured and executed"] +pub struct GetEntitlements<'a> { + http: &'a Client, + fields: GetEntitlementsFields<'a>, +} + +impl<'a> GetEntitlements<'a> { + pub(crate) const fn new(http: &'a Client) -> Self { + Self { + http, + fields: GetEntitlementsFields { + after: None, + before: None, + exclude_ended: None, + guild_id: None, + limit: None, + sku_ids: None, + user_id: None, + }, + } + } + + /// Retrieve entitlements after this time. + pub const fn after(mut self, after: EntitlementMarker) -> Self { + self.fields.after = Some(after); + + self + } + + /// Retrieve entitlements before this time. + pub const fn before(mut self, before: EntitlementMarker) -> Self { + self.fields.before = Some(before); + + self + } + + /// Whether to exclude ended entitlements. + pub const fn exclude_ended(mut self, exclude_ended: bool) -> Self { + self.fields.exclude_ended = Some(exclude_ended); + + self + } + + /// Guild ID to look up entitlements for. + pub const fn guild_id(mut self, guild_id: GuildMarker) -> Self { + self.fields.guild_id = Some(guild_id); + + self + } + + /// Number of entitlements to return. Set to 100 if unspecified. + /// + /// The minimum is 1 and the maximum is 100. + /// + /// # Errors + /// + /// Returns a [`GetEntitlementsError`] error type if the amount + /// is less than 1 or greater than 100. + /// + /// [`GetEntitlementsError`]: twilight_validate::request::ValidationErrorType::GetEntitlements + pub const fn limit(mut self, limit: u8) -> Result { + if let Err(source) = validate_get_entitlements_limit(limit) { + return Err(source); + } + + self.fields.limit = Some(limit); + + Ok(self) + } + + /// List of SKU IDs to check entitlements for. + pub const fn sku_ids(mut self, sku_ids: &'a [EntitlementSkuMarker]) -> Self { + self.fields.sku_ids = Some(sku_ids); + + self + } + + /// User ID to look up entitlements for. + pub const fn user_id(mut self, user_id: UserMarker) -> Self { + self.fields.user_id = Some(user_id); + + self + } +} diff --git a/twilight-http/src/request/application/monetization/mod.rs b/twilight-http/src/request/application/monetization/mod.rs new file mode 100644 index 00000000000..8e2b5b0b33e --- /dev/null +++ b/twilight-http/src/request/application/monetization/mod.rs @@ -0,0 +1 @@ +pub mod get_entitlements; diff --git a/twilight-model/src/id/mod.rs b/twilight-model/src/id/mod.rs index cc6e078dc50..6044dd414d1 100644 --- a/twilight-model/src/id/mod.rs +++ b/twilight-model/src/id/mod.rs @@ -418,9 +418,9 @@ mod tests { use super::{ marker::{ ApplicationMarker, AttachmentMarker, AuditLogEntryMarker, ChannelMarker, CommandMarker, - CommandVersionMarker, EmojiMarker, GenericMarker, GuildMarker, IntegrationMarker, - InteractionMarker, MessageMarker, RoleMarker, RoleSubscriptionSkuMarker, StageMarker, - UserMarker, WebhookMarker, + CommandVersionMarker, EmojiMarker, EntitlementMarker, EntitlementSkuMarker, + GenericMarker, GuildMarker, IntegrationMarker, InteractionMarker, MessageMarker, + RoleMarker, RoleSubscriptionSkuMarker, StageMarker, UserMarker, WebhookMarker, }, Id, }; @@ -443,6 +443,8 @@ mod tests { assert_impl_all!(CommandMarker: Debug, Send, Sync); assert_impl_all!(CommandVersionMarker: Debug, Send, Sync); assert_impl_all!(EmojiMarker: Debug, Send, Sync); + assert_impl_all!(EntitlementMarker: Debug, Send, Sync); + assert_impl_all!(EntitlementSkuMarker: Debug, Send, Sync); assert_impl_all!(GenericMarker: Debug, Send, Sync); assert_impl_all!(GuildMarker: Debug, Send, Sync); assert_impl_all!(IntegrationMarker: Debug, Send, Sync); @@ -661,6 +663,34 @@ mod tests { Token::U64(114_941_315_417_899_012), ], ); + serde_test::assert_tokens( + &Id::::new(114_941_315_417_899_012), + &[ + Token::NewtypeStruct { name: "Id" }, + Token::Str("114941315417899012"), + ], + ); + serde_test::assert_de_tokens( + &Id::::new(114_941_315_417_899_012), + &[ + Token::NewtypeStruct { name: "Id" }, + Token::Str("114941315417899012"), + ], + ); + serde_test::assert_tokens( + &Id::::new(114_941_315_417_899_012), + &[ + Token::NewtypeStruct { name: "Id" }, + Token::Str("114941315417899012"), + ], + ); + serde_test::assert_de_tokens( + &Id::::new(114_941_315_417_899_012), + &[ + Token::NewtypeStruct { name: "Id" }, + Token::Str("114941315417899012"), + ], + ); serde_test::assert_tokens( &Id::::new(114_941_315_417_899_012), &[ diff --git a/twilight-validate/src/request.rs b/twilight-validate/src/request.rs index f681144de1f..974fb2e3810 100644 --- a/twilight-validate/src/request.rs +++ b/twilight-validate/src/request.rs @@ -36,6 +36,12 @@ pub const GET_CURRENT_USER_GUILDS_LIMIT_MAX: u16 = 200; /// Minimum amount of guilds to get. pub const GET_CURRENT_USER_GUILDS_LIMIT_MIN: u16 = 1; +/// Maximum amount of entitlements to get. +pub const GET_ENTITLEMENTS_LIMIT_MAX: u8 = 100; + +/// Minimum amount of entitlements to get. +pub const GET_ENTITLEMENTS_LIMIT_MIN: u8 = 1; + /// Maximum amount of audit log entries to list. pub const GET_GUILD_AUDIT_LOG_LIMIT_MAX: u16 = 100; @@ -224,6 +230,15 @@ impl Display for ValidationError { Display::fmt(&GET_CURRENT_USER_GUILDS_LIMIT_MAX, f) } + ValidationErrorType::GetEntitlements { limit } => { + f.write_str("provided get entitlements limit is ")?; + Display::fmt(limit, f)?; + f.write_str(", but it must be at least ")?; + Display::fmt(&GET_ENTITLEMENTS_LIMIT_MIN, f)?; + f.write_str(" and at most ")?; + + Display::fmt(&GET_ENTITLEMENTS_LIMIT_MAX, f) + } ValidationErrorType::GetGuildAuditLog { limit } => { f.write_str("provided get guild audit log limit is ")?; Display::fmt(limit, f)?; @@ -428,6 +443,11 @@ pub enum ValidationErrorType { /// Invalid limit. limit: u16, }, + /// Provided get entitlements limit was invalid. + GetEntitlements { + /// Invalid limit. + limit: u8, + }, /// Provided get guild audit log limit was invalid. GetGuildAuditLog { /// Invalid limit. @@ -687,6 +707,28 @@ pub const fn get_current_user_guilds_limit(limit: u16) -> Result<(), ValidationE } } +/// Ensure that the limit for the Get Entitlements endpoint is correct. +/// +/// The limit must be at least [`GET_ENTITLEMENTS_LIMIT_MIN`] and at most +/// [`GET_ENTITLEMENTS_LIMIT_MAX`]. This is based on +/// [this documentation entry]. +/// +/// # Errors +/// +/// Returns an error of type [`GetEntitlements`] if the limit is invalid. +/// +/// [`GetEntitlements`]: ValidationErrorType::GetEntitlements +/// [this documentation entry]: https://discord.com/developers/docs/monetization/entitlements#list-entitlements +pub const fn get_entitlements_limit(limit: u8) -> Result<(), ValidationError> { + if limit >= GET_ENTITLEMENTS_LIMIT_MIN && limit <= GET_ENTITLEMENTS_LIMIT_MAX { + Ok(()) + } else { + Err(ValidationError { + kind: ValidationErrorType::GetEntitlements { limit }, + }) + } +} + /// Ensure that the limit for the Get Guild Audit Log endpoint is correct. /// /// The limit must be at least [`GET_GUILD_AUDIT_LOG_LIMIT_MIN`] and at most From 8b6cd8d5d03170450f7241225145506d63b38110 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Tue, 26 Sep 2023 20:20:56 -0400 Subject: [PATCH 03/21] add get entitlements route --- twilight-http-ratelimiting/src/request.rs | 3 + twilight-http/src/client/mod.rs | 28 +++++- .../monetization/get_entitlements.rs | 77 ++++++++++++---- .../request/application/monetization/mod.rs | 2 + twilight-http/src/request/try_into_request.rs | 2 + twilight-http/src/routing.rs | 89 ++++++++++++++++++- 6 files changed, 183 insertions(+), 18 deletions(-) diff --git a/twilight-http-ratelimiting/src/request.rs b/twilight-http-ratelimiting/src/request.rs index f5351a9d18c..cc6a4447a1e 100644 --- a/twilight-http-ratelimiting/src/request.rs +++ b/twilight-http-ratelimiting/src/request.rs @@ -162,6 +162,8 @@ pub enum Path { ChannelsIdTyping(u64), /// Operating on a channel's webhooks. ChannelsIdWebhooks(u64), + /// Operating on an applications's entitlements. + ApplicationIdEntitlements(u64), /// Operating with the gateway information. Gateway, /// Operating with the gateway information tailored to the current user. @@ -332,6 +334,7 @@ impl FromStr for Path { Ok(match parts[..] { ["applications", id, "commands"] => ApplicationCommand(parse_id(id)?), ["applications", id, "commands", _] => ApplicationCommandId(parse_id(id)?), + ["applications", id, "entitlements"] => ApplicationIdEntitlements(parse_id(id)?), ["applications", id, "guilds", _, "commands"] | ["applications", id, "guilds", _, "commands", "permissions"] => { ApplicationGuildCommand(parse_id(id)?) diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index b5fe91a9f1f..9838e3dcb23 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -4,7 +4,10 @@ mod interaction; pub use self::{builder::ClientBuilder, interaction::InteractionClient}; -use crate::request::{guild::GetGuildOnboarding, GetCurrentAuthorizationInformation}; +use crate::request::{ + application::monetization::GetEntitlements, guild::GetGuildOnboarding, + GetCurrentAuthorizationInformation, +}; #[allow(deprecated)] use crate::{ client::connector::Connector, @@ -774,6 +777,29 @@ impl Client { GetEmojis::new(self, guild_id) } + /// Get the entitlements for an application. + /// + /// # Examples + /// + /// Get emojis for the application `100`: + /// + /// ```no_run + /// # use twilight_http::Client; + /// # use twilight_model::id::Id; + /// + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// # let client = Client::new("my token".to_owned()); + /// # + /// let application_id = Id::new(100); + /// + /// client.entitlements(application_id).await?; + /// # Ok(()) } + /// ``` + pub const fn entitlements(&self, application_id: Id) -> GetEntitlements<'_> { + GetEntitlements::new(self, application_id) + } + /// Get an emoji for a guild by the the guild's ID and emoji's ID. /// /// # Examples diff --git a/twilight-http/src/request/application/monetization/get_entitlements.rs b/twilight-http/src/request/application/monetization/get_entitlements.rs index 4d641d9f4ca..83c43842889 100644 --- a/twilight-http/src/request/application/monetization/get_entitlements.rs +++ b/twilight-http/src/request/application/monetization/get_entitlements.rs @@ -1,33 +1,48 @@ -use twilight_model::id::marker::{ - EntitlementMarker, EntitlementSkuMarker, GuildMarker, UserMarker, +use std::future::IntoFuture; + +use twilight_model::{ + application::monetization::Entitlement, + id::{ + marker::{ + ApplicationMarker, EntitlementMarker, EntitlementSkuMarker, GuildMarker, UserMarker, + }, + Id, + }, }; -use crate::Client; +use crate::{ + request::{Request, TryIntoRequest}, + response::{marker::ListBody, ResponseFuture}, + routing::Route, + Client, Error, Response, +}; use twilight_validate::request::{ get_entitlements_limit as validate_get_entitlements_limit, ValidationError, }; struct GetEntitlementsFields<'a> { - after: Option, - before: Option, + after: Option>, + before: Option>, exclude_ended: Option, - guild_id: Option, + guild_id: Option>, limit: Option, - sku_ids: Option<&'a [EntitlementSkuMarker]>, - user_id: Option, + sku_ids: &'a [Id], + user_id: Option>, } /// Get all entitlements for a given app, active and expired. #[must_use = "requests must be configured and executed"] pub struct GetEntitlements<'a> { + application_id: Id, http: &'a Client, fields: GetEntitlementsFields<'a>, } impl<'a> GetEntitlements<'a> { - pub(crate) const fn new(http: &'a Client) -> Self { + pub(crate) const fn new(http: &'a Client, application_id: Id) -> Self { Self { + application_id, http, fields: GetEntitlementsFields { after: None, @@ -35,21 +50,21 @@ impl<'a> GetEntitlements<'a> { exclude_ended: None, guild_id: None, limit: None, - sku_ids: None, + sku_ids: &[], user_id: None, }, } } /// Retrieve entitlements after this time. - pub const fn after(mut self, after: EntitlementMarker) -> Self { + pub const fn after(mut self, after: Id) -> Self { self.fields.after = Some(after); self } /// Retrieve entitlements before this time. - pub const fn before(mut self, before: EntitlementMarker) -> Self { + pub const fn before(mut self, before: Id) -> Self { self.fields.before = Some(before); self @@ -63,7 +78,7 @@ impl<'a> GetEntitlements<'a> { } /// Guild ID to look up entitlements for. - pub const fn guild_id(mut self, guild_id: GuildMarker) -> Self { + pub const fn guild_id(mut self, guild_id: Id) -> Self { self.fields.guild_id = Some(guild_id); self @@ -90,16 +105,46 @@ impl<'a> GetEntitlements<'a> { } /// List of SKU IDs to check entitlements for. - pub const fn sku_ids(mut self, sku_ids: &'a [EntitlementSkuMarker]) -> Self { - self.fields.sku_ids = Some(sku_ids); + pub const fn sku_ids(mut self, sku_ids: &'a [Id]) -> Self { + self.fields.sku_ids = sku_ids; self } /// User ID to look up entitlements for. - pub const fn user_id(mut self, user_id: UserMarker) -> Self { + pub const fn user_id(mut self, user_id: Id) -> Self { self.fields.user_id = Some(user_id); self } } + +impl IntoFuture for GetEntitlements<'_> { + type Output = Result>, Error>; + + type IntoFuture = ResponseFuture>; + + fn into_future(self) -> Self::IntoFuture { + let http = self.http; + + match self.try_into_request() { + Ok(request) => http.request(request), + Err(source) => ResponseFuture::error(source), + } + } +} + +impl TryIntoRequest for GetEntitlements<'_> { + fn try_into_request(self) -> Result { + Ok(Request::from_route(&Route::GetEntitlements { + after: self.fields.after.map(Id::get), + application_id: self.application_id.get(), + before: self.fields.before.map(Id::get), + exclude_ended: self.fields.exclude_ended, + guild_id: self.fields.guild_id.map(Id::get), + limit: self.fields.limit, + sku_ids: self.fields.sku_ids, + user_id: self.fields.user_id.map(Id::get), + })) + } +} diff --git a/twilight-http/src/request/application/monetization/mod.rs b/twilight-http/src/request/application/monetization/mod.rs index 8e2b5b0b33e..2071e7b78a6 100644 --- a/twilight-http/src/request/application/monetization/mod.rs +++ b/twilight-http/src/request/application/monetization/mod.rs @@ -1 +1,3 @@ pub mod get_entitlements; + +pub use self::get_entitlements::GetEntitlements; diff --git a/twilight-http/src/request/try_into_request.rs b/twilight-http/src/request/try_into_request.rs index c2df5f0faec..ec086ec344c 100644 --- a/twilight-http/src/request/try_into_request.rs +++ b/twilight-http/src/request/try_into_request.rs @@ -18,6 +18,7 @@ mod private { CreateFollowup, CreateResponse, DeleteFollowup, DeleteResponse, GetFollowup, GetResponse, UpdateFollowup, UpdateResponse, }, + monetization::get_entitlements::GetEntitlements, }, channel::{ invite::{CreateInvite, DeleteInvite, GetChannelInvites, GetInvite}, @@ -177,6 +178,7 @@ mod private { impl Sealed for GetCurrentUserGuilds<'_> {} impl Sealed for GetEmoji<'_> {} impl Sealed for GetEmojis<'_> {} + impl Sealed for GetEntitlements<'_> {} impl Sealed for GetFollowup<'_> {} impl Sealed for GetGateway<'_> {} impl Sealed for GetGatewayAuthed<'_> {} diff --git a/twilight-http/src/routing.rs b/twilight-http/src/routing.rs index 82466e57b45..3850720196a 100644 --- a/twilight-http/src/routing.rs +++ b/twilight-http/src/routing.rs @@ -3,7 +3,10 @@ pub use twilight_http_ratelimiting::request::{Path, PathParseError, PathParseErr use crate::request::{channel::reaction::RequestReactionType, Method}; use std::fmt::{Display, Formatter, Result as FmtResult}; -use twilight_model::id::{marker::RoleMarker, Id}; +use twilight_model::id::{ + marker::{EntitlementSkuMarker, RoleMarker}, + Id, +}; #[derive(Clone, Debug, Eq, Hash, PartialEq)] #[non_exhaustive] @@ -453,6 +456,24 @@ pub enum Route<'a> { /// The ID of the guild. guild_id: u64, }, + GetEntitlements { + /// Retrieve entitlements after this time. + after: Option, + /// The ID of the application. + application_id: u64, + /// Retrieve entitlements before this time. + before: Option, + /// Whether to exclude ended entitlements. + exclude_ended: Option, + /// Guild ID to look up entitlements for. + guild_id: Option, + /// Number of entitlements to return. Set to 100 if unspecified. + limit: Option, + /// List of SKU IDs to check entitlements for. + sku_ids: &'a [Id], + /// User ID to look up entitlements for. + user_id: Option, + }, /// Route to get a followup message for an interaction. GetFollowupMessage { /// ID of the application. @@ -1166,6 +1187,7 @@ impl<'a> Route<'a> { | Self::GetCurrentUserGuildMember { .. } | Self::GetEmoji { .. } | Self::GetEmojis { .. } + | Self::GetEntitlements { .. } | Self::GetGateway | Self::GetFollowupMessage { .. } | Self::GetGlobalCommand { .. } @@ -1538,6 +1560,9 @@ impl<'a> Route<'a> { Self::GetEmoji { guild_id, .. } | Self::UpdateEmoji { guild_id, .. } => { Path::GuildsIdEmojisId(guild_id) } + Self::GetEntitlements { application_id, .. } => { + Path::ApplicationIdEntitlements(application_id) + } Self::GetGateway => Path::Gateway, Self::GetGuild { guild_id, .. } | Self::UpdateGuild { guild_id } => { Path::GuildsId(guild_id) @@ -1959,6 +1984,68 @@ impl Display for Route<'_> { Display::fmt(emoji_id, f) } + Route::GetEntitlements { + after, + application_id, + before, + exclude_ended, + guild_id, + limit, + sku_ids, + user_id, + } => { + f.write_str("applications/")?; + Display::fmt(application_id, f)?; + f.write_str("/entitlements")?; + + f.write_str("?")?; + + if let Some(after) = after { + f.write_str("after=")?; + Display::fmt(after, f)?; + } + + if let Some(before) = before { + f.write_str("&before=")?; + Display::fmt(before, f)?; + } + + if let Some(exclude_ended) = exclude_ended { + f.write_str("&exclude_ended=")?; + Display::fmt(exclude_ended, f)?; + } + + if let Some(guild_id) = guild_id { + f.write_str("&guild_id=")?; + Display::fmt(guild_id, f)?; + } + + if let Some(limit) = limit { + f.write_str("&limit=")?; + Display::fmt(limit, f)?; + } + + if !sku_ids.is_empty() { + let sku_id_count = sku_ids.len() - 1; + + f.write_str("&sku_ids=")?; + + for (idx, sku_id) in sku_ids.iter().enumerate() { + Display::fmt(sku_id, f)?; + + if idx < sku_id_count { + f.write_str(",")?; + } + } + } + + if let Some(user_id) = user_id { + f.write_str("&user_id=")?; + Display::fmt(user_id, f)?; + } + + Ok(()) + } Route::DeleteGlobalCommand { application_id, command_id, From d1f5b20104f68dad9248d2846bf4757517d6f630 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 15:10:07 -0400 Subject: [PATCH 04/21] Add create test entitlement route --- twilight-http/src/client/mod.rs | 45 +++++- .../monetization/create_test_entitlement.rs | 136 ++++++++++++++++++ .../request/application/monetization/mod.rs | 1 + twilight-http/src/request/try_into_request.rs | 5 +- twilight-http/src/routing.rs | 44 +++++- 5 files changed, 223 insertions(+), 8 deletions(-) create mode 100644 twilight-http/src/request/application/monetization/create_test_entitlement.rs diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index 9838e3dcb23..adf38e93d23 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -5,7 +5,11 @@ mod interaction; pub use self::{builder::ClientBuilder, interaction::InteractionClient}; use crate::request::{ - application::monetization::GetEntitlements, guild::GetGuildOnboarding, + application::monetization::{ + create_test_entitlement::{CreateTestEntitlement, CreateTestEntitlementOwner}, + GetEntitlements, + }, + guild::GetGuildOnboarding, GetCurrentAuthorizationInformation, }; #[allow(deprecated)] @@ -108,9 +112,9 @@ use twilight_model::{ http::permission_overwrite::PermissionOverwrite, id::{ marker::{ - ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker, GuildMarker, - IntegrationMarker, MessageMarker, RoleMarker, ScheduledEventMarker, StickerMarker, - UserMarker, WebhookMarker, + ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker, + EntitlementSkuMarker, GuildMarker, IntegrationMarker, MessageMarker, RoleMarker, + ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, }, Id, }, @@ -2576,6 +2580,39 @@ impl Client { DeleteGuildSticker::new(self, guild_id, sticker_id) } + /// Creates a test entitlement to a given SKU for a given guild or user. Discord + /// will act as though that user or guild has entitlement to your premium offering. + /// + /// # Examples + /// + /// ```no_run + /// use twilight_http::{Client, request::application::entitlement::CreateTestEntitlementOwner}; + /// use twilight_model::id::Id; + /// + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = Client::new("my token".to_owned()); + /// + /// let application_id = Id::new(1); + /// let sku_id = Id::new(2); + /// let owner = CreateTestEntitlementOwner::Guild(Id::new(3)); + /// + /// client.create_test_entitlement( + /// application_id, + /// sku_id, + /// owner, + /// ).await?; + /// + /// # Ok(()) } + pub const fn create_test_entitlement( + &self, + application_id: Id, + sku_id: Id, + owner: CreateTestEntitlementOwner, + ) -> CreateTestEntitlement<'_> { + CreateTestEntitlement::new(self, application_id, sku_id, owner) + } + /// Execute a request, returning a future resolving to a [`Response`]. /// /// # Errors diff --git a/twilight-http/src/request/application/monetization/create_test_entitlement.rs b/twilight-http/src/request/application/monetization/create_test_entitlement.rs new file mode 100644 index 00000000000..dddce516729 --- /dev/null +++ b/twilight-http/src/request/application/monetization/create_test_entitlement.rs @@ -0,0 +1,136 @@ +use std::future::IntoFuture; + +use serde::ser::{Serialize, SerializeStruct, Serializer}; +use twilight_model::{ + application::monetization::Entitlement, + id::{ + marker::{ApplicationMarker, EntitlementSkuMarker, GuildMarker, UserMarker}, + Id, + }, +}; + +use crate::{ + request::{Request, RequestBuilder, TryIntoRequest}, + response::ResponseFuture, + routing::Route, + Client, Error, Response, +}; + +/// Owner of a test entitlement. +pub enum CreateTestEntitlementOwner { + Guild(Id), + User(Id), +} + +impl CreateTestEntitlementOwner { + pub const fn id(&self) -> u64 { + match self { + CreateTestEntitlementOwner::Guild(id) => id.get(), + CreateTestEntitlementOwner::User(id) => id.get(), + } + } + + pub const fn kind(&self) -> u8 { + match self { + CreateTestEntitlementOwner::Guild(_) => 1, + CreateTestEntitlementOwner::User(_) => 2, + } + } +} + +struct CreateTestEntitlementFields { + sku_id: Id, + owner: CreateTestEntitlementOwner, +} + +impl Serialize for CreateTestEntitlementFields { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_struct("CreateTestEntitlementFields", 2)?; + state.serialize_field("sku_id", &self.sku_id.get())?; + state.serialize_field("owner_id", &self.owner.id())?; + state.serialize_field("owner_type", &self.owner.kind())?; + state.end() + } +} + +pub struct CreateTestEntitlement<'a> { + application_id: Id, + fields: CreateTestEntitlementFields, + http: &'a Client, +} + +impl<'a> CreateTestEntitlement<'a> { + pub(crate) const fn new( + http: &'a Client, + application_id: Id, + sku_id: Id, + owner: CreateTestEntitlementOwner, + ) -> Self { + Self { + application_id, + fields: CreateTestEntitlementFields { sku_id, owner }, + http, + } + } +} + +impl IntoFuture for CreateTestEntitlement<'_> { + type Output = Result, Error>; + + type IntoFuture = ResponseFuture; + + fn into_future(self) -> Self::IntoFuture { + let http = self.http; + + match self.try_into_request() { + Ok(request) => http.request(request), + Err(source) => ResponseFuture::error(source), + } + } +} + +impl TryIntoRequest for CreateTestEntitlement<'_> { + fn try_into_request(self) -> Result { + Request::builder(&Route::CreateTestEntitlement { + application_id: self.application_id.get(), + }) + .json(&self.fields) + .map(RequestBuilder::build) + } +} + +#[cfg(test)] +mod tests { + use serde_test::Token; + use twilight_model::id::Id; + + use super::{CreateTestEntitlementFields, CreateTestEntitlementOwner}; + + #[test] + fn fields_serialization() { + let value = CreateTestEntitlementFields { + sku_id: Id::new(1), + owner: CreateTestEntitlementOwner::Guild(Id::new(2)), + }; + + serde_test::assert_ser_tokens( + &value, + &[ + Token::Struct { + name: "CreateTestEntitlementFields", + len: 2, + }, + Token::Str("sku_id"), + Token::U64(1), + Token::Str("owner_id"), + Token::U64(2), + Token::Str("owner_type"), + Token::U8(1), + Token::StructEnd, + ], + ); + } +} diff --git a/twilight-http/src/request/application/monetization/mod.rs b/twilight-http/src/request/application/monetization/mod.rs index 2071e7b78a6..4a3dc3ef807 100644 --- a/twilight-http/src/request/application/monetization/mod.rs +++ b/twilight-http/src/request/application/monetization/mod.rs @@ -1,3 +1,4 @@ +pub mod create_test_entitlement; pub mod get_entitlements; pub use self::get_entitlements::GetEntitlements; diff --git a/twilight-http/src/request/try_into_request.rs b/twilight-http/src/request/try_into_request.rs index ec086ec344c..125f095ac2e 100644 --- a/twilight-http/src/request/try_into_request.rs +++ b/twilight-http/src/request/try_into_request.rs @@ -18,7 +18,9 @@ mod private { CreateFollowup, CreateResponse, DeleteFollowup, DeleteResponse, GetFollowup, GetResponse, UpdateFollowup, UpdateResponse, }, - monetization::get_entitlements::GetEntitlements, + monetization::{ + create_test_entitlement::CreateTestEntitlement, get_entitlements::GetEntitlements, + }, }, channel::{ invite::{CreateInvite, DeleteInvite, GetChannelInvites, GetInvite}, @@ -126,6 +128,7 @@ mod private { impl Sealed for CreateRole<'_> {} impl Sealed for CreateStageInstance<'_> {} impl Sealed for CreateTemplate<'_> {} + impl Sealed for CreateTestEntitlement<'_> {} impl Sealed for CreateThread<'_> {} impl Sealed for CreateThreadFromMessage<'_> {} impl Sealed for CreateTypingTrigger<'_> {} diff --git a/twilight-http/src/routing.rs b/twilight-http/src/routing.rs index 3850720196a..70276827e80 100644 --- a/twilight-http/src/routing.rs +++ b/twilight-http/src/routing.rs @@ -138,6 +138,10 @@ pub enum Route<'a> { /// The ID of the guild. guild_id: u64, }, + CreateTestEntitlement { + /// The ID of the application. + application_id: u64, + }, /// Route information to create a thread in a channel. CreateThread { /// ID of the channel. @@ -1288,6 +1292,7 @@ impl<'a> Route<'a> { | Self::CreateRole { .. } | Self::CreateStageInstance { .. } | Self::CreateTemplate { .. } + | Self::CreateTestEntitlement { .. } | Self::CreateTypingTrigger { .. } | Self::CreateWebhook { .. } | Self::CrosspostMessage { .. } @@ -1428,6 +1433,10 @@ impl<'a> Route<'a> { Self::CreateThreadFromMessage { channel_id, .. } => { Path::ChannelsIdMessagesIdThreads(channel_id) } + Self::CreateTestEntitlement { application_id } + | Self::GetEntitlements { application_id, .. } => { + Path::ApplicationIdEntitlements(application_id) + } Self::CreateTypingTrigger { channel_id } => Path::ChannelsIdTyping(channel_id), Self::CreateWebhook { channel_id } | Self::GetChannelWebhooks { channel_id } => { Path::ChannelsIdWebhooks(channel_id) @@ -1560,9 +1569,6 @@ impl<'a> Route<'a> { Self::GetEmoji { guild_id, .. } | Self::UpdateEmoji { guild_id, .. } => { Path::GuildsIdEmojisId(guild_id) } - Self::GetEntitlements { application_id, .. } => { - Path::ApplicationIdEntitlements(application_id) - } Self::GetGateway => Path::Gateway, Self::GetGuild { guild_id, .. } | Self::UpdateGuild { guild_id } => { Path::GuildsId(guild_id) @@ -1814,6 +1820,12 @@ impl Display for Route<'_> { f.write_str(template_code) } + Route::CreateTestEntitlement { application_id } => { + f.write_str("applications/")?; + Display::fmt(application_id, f)?; + + f.write_str("/entitlements") + } Route::CreateGuildIntegration { guild_id } | Route::GetGuildIntegrations { guild_id } => { f.write_str("guilds/")?; @@ -4046,6 +4058,32 @@ mod tests { assert_eq!(route.to_string(), "gateway/bot"); } + #[test] + fn get_entitlements() { + let route = Route::GetEntitlements { + after: Some(32), + application_id: 1, + before: Some(2), + exclude_ended: Some(true), + guild_id: Some(42), + limit: Some(99), + sku_ids: &[Id::new(7)], + user_id: Some(11), + }; + + assert_eq!( + route.to_string(), + "applications/1/entitlements?after=32&before=2&exclude_ended=true&guild_id=42&limit=99&sku_ids=7&user_id=11" + ); + } + + #[test] + fn create_test_entitlement() { + let route = Route::CreateTestEntitlement { application_id: 1 }; + + assert_eq!(route.to_string(), "applications/1/entitlements"); + } + #[test] fn get_command_permissions() { let route = Route::GetCommandPermissions { From eec8e2144a832285c8865bb54fa158c186080ec7 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 19:06:17 -0400 Subject: [PATCH 05/21] add delete test entitlement route --- twilight-http/src/client/mod.rs | 16 ++++- .../monetization/delete_test_entitlement.rs | 58 +++++++++++++++++++ .../request/application/monetization/mod.rs | 3 + twilight-http/src/request/try_into_request.rs | 2 + twilight-http/src/routing.rs | 20 ++++++- 5 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 twilight-http/src/request/application/monetization/delete_test_entitlement.rs diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index adf38e93d23..05a653f326b 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -7,7 +7,7 @@ pub use self::{builder::ClientBuilder, interaction::InteractionClient}; use crate::request::{ application::monetization::{ create_test_entitlement::{CreateTestEntitlement, CreateTestEntitlementOwner}, - GetEntitlements, + DeleteTestEntitlement, GetEntitlements, }, guild::GetGuildOnboarding, GetCurrentAuthorizationInformation, @@ -113,8 +113,8 @@ use twilight_model::{ id::{ marker::{ ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker, - EntitlementSkuMarker, GuildMarker, IntegrationMarker, MessageMarker, RoleMarker, - ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, + EntitlementMarker, EntitlementSkuMarker, GuildMarker, IntegrationMarker, MessageMarker, + RoleMarker, ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, }, Id, }, @@ -2613,6 +2613,16 @@ impl Client { CreateTestEntitlement::new(self, application_id, sku_id, owner) } + /// Deletes a currently-active test entitlement. Discord will act as though that user or + /// guild no longer has entitlement to your premium offering. + pub const fn delete_test_entitlement( + &self, + application_id: Id, + entitlement_id: Id, + ) -> DeleteTestEntitlement<'_> { + DeleteTestEntitlement::new(self, application_id, entitlement_id) + } + /// Execute a request, returning a future resolving to a [`Response`]. /// /// # Errors diff --git a/twilight-http/src/request/application/monetization/delete_test_entitlement.rs b/twilight-http/src/request/application/monetization/delete_test_entitlement.rs new file mode 100644 index 00000000000..db72780b1b8 --- /dev/null +++ b/twilight-http/src/request/application/monetization/delete_test_entitlement.rs @@ -0,0 +1,58 @@ +use std::future::IntoFuture; + +use twilight_model::id::{ + marker::{ApplicationMarker, EntitlementMarker}, + Id, +}; + +use crate::{ + request::{Request, TryIntoRequest}, + response::{marker::EmptyBody, ResponseFuture}, + routing::Route, + Client, Error, Response, +}; + +pub struct DeleteTestEntitlement<'a> { + application_id: Id, + entitlement_id: Id, + http: &'a Client, +} + +impl<'a> DeleteTestEntitlement<'a> { + pub(crate) const fn new( + http: &'a Client, + application_id: Id, + entitlement_id: Id, + ) -> Self { + Self { + application_id, + entitlement_id, + http, + } + } +} + +impl IntoFuture for DeleteTestEntitlement<'_> { + type Output = Result, Error>; + + type IntoFuture = ResponseFuture; + + fn into_future(self) -> Self::IntoFuture { + let http = self.http; + + match self.try_into_request() { + Ok(request) => http.request(request), + Err(source) => ResponseFuture::error(source), + } + } +} + +impl TryIntoRequest for DeleteTestEntitlement<'_> { + fn try_into_request(self) -> Result { + Ok(Request::builder(&Route::DeleteTestEntitlement { + application_id: self.application_id.get(), + entitlement_id: self.entitlement_id.get(), + }) + .build()) + } +} diff --git a/twilight-http/src/request/application/monetization/mod.rs b/twilight-http/src/request/application/monetization/mod.rs index 4a3dc3ef807..11fdb8dd257 100644 --- a/twilight-http/src/request/application/monetization/mod.rs +++ b/twilight-http/src/request/application/monetization/mod.rs @@ -1,4 +1,7 @@ pub mod create_test_entitlement; +pub mod delete_test_entitlement; pub mod get_entitlements; +pub use self::create_test_entitlement::{CreateTestEntitlement, CreateTestEntitlementOwner}; +pub use self::delete_test_entitlement::DeleteTestEntitlement; pub use self::get_entitlements::GetEntitlements; diff --git a/twilight-http/src/request/try_into_request.rs b/twilight-http/src/request/try_into_request.rs index 125f095ac2e..dc18316e700 100644 --- a/twilight-http/src/request/try_into_request.rs +++ b/twilight-http/src/request/try_into_request.rs @@ -20,6 +20,7 @@ mod private { }, monetization::{ create_test_entitlement::CreateTestEntitlement, get_entitlements::GetEntitlements, + DeleteTestEntitlement, }, }, channel::{ @@ -160,6 +161,7 @@ mod private { impl Sealed for DeleteTemplate<'_> {} impl Sealed for DeleteWebhook<'_> {} impl Sealed for DeleteWebhookMessage<'_> {} + impl Sealed for DeleteTestEntitlement<'_> {} impl Sealed for ExecuteWebhook<'_> {} impl Sealed for ExecuteWebhookAndWait<'_> {} impl Sealed for FollowNewsChannel<'_> {} diff --git a/twilight-http/src/routing.rs b/twilight-http/src/routing.rs index 70276827e80..06970038df0 100644 --- a/twilight-http/src/routing.rs +++ b/twilight-http/src/routing.rs @@ -342,6 +342,12 @@ pub enum Route<'a> { token: &'a str, webhook_id: u64, }, + DeleteTestEntitlement { + /// The ID of the application. + application_id: u64, + /// The ID of the entitlement. + entitlement_id: u64, + }, /// Route information to execute a webhook by ID and token. ExecuteWebhook { /// ID of the thread channel, if there is one. @@ -1154,6 +1160,7 @@ impl<'a> Route<'a> { | Self::DeleteGuildIntegration { .. } | Self::DeleteGuildScheduledEvent { .. } | Self::DeleteGuildSticker { .. } + | Self::DeleteTestEntitlement { .. } | Self::DeleteInteractionOriginal { .. } | Self::DeleteInvite { .. } | Self::DeleteMessageReactions { .. } @@ -1434,7 +1441,8 @@ impl<'a> Route<'a> { Path::ChannelsIdMessagesIdThreads(channel_id) } Self::CreateTestEntitlement { application_id } - | Self::GetEntitlements { application_id, .. } => { + | Self::GetEntitlements { application_id, .. } + | Self::DeleteTestEntitlement { application_id, .. } => { Path::ApplicationIdEntitlements(application_id) } Self::CreateTypingTrigger { channel_id } => Path::ChannelsIdTyping(channel_id), @@ -2328,6 +2336,16 @@ impl Display for Route<'_> { Ok(()) } + Route::DeleteTestEntitlement { + application_id, + entitlement_id, + } => { + f.write_str("applications/")?; + Display::fmt(application_id, f)?; + f.write_str("/entitlements/")?; + + Display::fmt(entitlement_id, f) + } Route::FollowNewsChannel { channel_id } => { f.write_str("channels/")?; Display::fmt(channel_id, f)?; From 3509480a997fd28613eb0c4ba805fcd19bcc911d Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 22:49:56 -0400 Subject: [PATCH 06/21] entitlement create event --- twilight-cache-inmemory/src/lib.rs | 1 + twilight-gateway/src/event.rs | 3 +++ twilight-model/src/gateway/event/dispatch.rs | 5 +++++ twilight-model/src/gateway/event/kind.rs | 4 ++++ twilight-model/src/gateway/event/mod.rs | 5 +++++ .../payload/incoming/entitlement_create.rs | 20 +++++++++++++++++++ .../src/gateway/payload/incoming/mod.rs | 3 ++- 7 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 twilight-model/src/gateway/payload/incoming/entitlement_create.rs diff --git a/twilight-cache-inmemory/src/lib.rs b/twilight-cache-inmemory/src/lib.rs index 981a13eab87..e9c2b58bafc 100644 --- a/twilight-cache-inmemory/src/lib.rs +++ b/twilight-cache-inmemory/src/lib.rs @@ -899,6 +899,7 @@ impl UpdateCache for Event { | Event::BanAdd(_) | Event::BanRemove(_) | Event::CommandPermissionsUpdate(_) + | Event::EntitlementCreate(_) | Event::GatewayClose(_) | Event::GatewayHeartbeat(_) | Event::GatewayHeartbeatAck diff --git a/twilight-gateway/src/event.rs b/twilight-gateway/src/event.rs index 5fe1814e7dc..38ef0ad6c3d 100644 --- a/twilight-gateway/src/event.rs +++ b/twilight-gateway/src/event.rs @@ -50,6 +50,8 @@ bitflags! { /// /// [`AutoModerationRule`]: crate::guild::auto_moderation::AutoModerationRule const AUTO_MODERATION_RULE_UPDATE = 1 << 74; + /// An entitlement has been created. + const ENTITLEMENT_CREATE = 1 << 76; /// User has been banned from a guild. const BAN_ADD = 1; /// User has been unbanned from a guild. @@ -340,6 +342,7 @@ impl From for EventTypeFlags { EventType::ChannelPinsUpdate => Self::CHANNEL_PINS_UPDATE, EventType::ChannelUpdate => Self::CHANNEL_UPDATE, EventType::CommandPermissionsUpdate => Self::COMMAND_PERMISSIONS_UPDATE, + EventType::EntitlementCreate => Self::ENTITLEMENT_CREATE, EventType::GatewayClose => Self::empty(), EventType::GatewayHeartbeat => Self::GATEWAY_HEARTBEAT, EventType::GatewayHeartbeatAck => Self::GATEWAY_HEARTBEAT_ACK, diff --git a/twilight-model/src/gateway/event/dispatch.rs b/twilight-model/src/gateway/event/dispatch.rs index d3722408406..121440010dc 100644 --- a/twilight-model/src/gateway/event/dispatch.rs +++ b/twilight-model/src/gateway/event/dispatch.rs @@ -25,6 +25,7 @@ pub enum DispatchEvent { ChannelPinsUpdate(ChannelPinsUpdate), ChannelUpdate(Box), CommandPermissionsUpdate(CommandPermissionsUpdate), + EntitlementCreate(EntitlementCreate), GiftCodeUpdate, GuildAuditLogEntryCreate(Box), GuildCreate(Box), @@ -95,6 +96,7 @@ impl DispatchEvent { Self::ChannelPinsUpdate(_) => EventType::ChannelPinsUpdate, Self::ChannelUpdate(_) => EventType::ChannelUpdate, Self::CommandPermissionsUpdate(_) => EventType::CommandPermissionsUpdate, + Self::EntitlementCreate(_) => EventType::EntitlementCreate, Self::GiftCodeUpdate => EventType::GiftCodeUpdate, Self::GuildAuditLogEntryCreate(_) => EventType::GuildAuditLogEntryCreate, Self::GuildCreate(_) => EventType::GuildCreate, @@ -272,6 +274,9 @@ impl<'de, 'a> DeserializeSeed<'de> for DispatchEventWithTypeDeserializer<'a> { "APPLICATION_COMMAND_PERMISSIONS_UPDATE" => DispatchEvent::CommandPermissionsUpdate( CommandPermissionsUpdate::deserialize(deserializer)?, ), + "ENTITLEMENT_CREATE" => { + DispatchEvent::EntitlementCreate(EntitlementCreate::deserialize(deserializer)?) + } "GIFT_CODE_UPDATE" => { deserializer.deserialize_ignored_any(IgnoredAny)?; diff --git a/twilight-model/src/gateway/event/kind.rs b/twilight-model/src/gateway/event/kind.rs index 7e03c9bc982..eca5b3042ba 100644 --- a/twilight-model/src/gateway/event/kind.rs +++ b/twilight-model/src/gateway/event/kind.rs @@ -18,6 +18,7 @@ pub enum EventType { ChannelUpdate, #[serde(rename = "APPLICATION_COMMAND_PERMISSIONS_UPDATE")] CommandPermissionsUpdate, + EntitlementCreate, GatewayClose, GatewayHeartbeat, GatewayHeartbeatAck, @@ -104,6 +105,7 @@ impl EventType { Self::ChannelPinsUpdate => Some("CHANNEL_PINS_UPDATE"), Self::ChannelUpdate => Some("CHANNEL_UPDATE"), Self::CommandPermissionsUpdate => Some("APPLICATION_COMMAND_PERMISSIONS_UPDATE"), + Self::EntitlementCreate => Some("ENTITLEMENT_CREATE"), Self::GiftCodeUpdate => Some("GIFT_CODE_UPDATE"), Self::GuildAuditLogEntryCreate => Some("GUILD_AUDIT_LOG_ENTRY_CREATE"), Self::GuildCreate => Some("GUILD_CREATE"), @@ -184,6 +186,7 @@ impl<'a> TryFrom<&'a str> for EventType { "CHANNEL_PINS_UPDATE" => Ok(Self::ChannelPinsUpdate), "CHANNEL_UPDATE" => Ok(Self::ChannelUpdate), "APPLICATION_COMMAND_PERMISSIONS_UPDATE" => Ok(Self::CommandPermissionsUpdate), + "ENTITLEMENT_CREATE" => Ok(Self::EntitlementCreate), "GIFT_CODE_UPDATE" => Ok(Self::GiftCodeUpdate), "GUILD_CREATE" => Ok(Self::GuildCreate), "GUILD_DELETE" => Ok(Self::GuildDelete), @@ -369,5 +372,6 @@ mod tests { assert_variant(EventType::VoiceServerUpdate, "VOICE_SERVER_UPDATE"); assert_variant(EventType::VoiceStateUpdate, "VOICE_STATE_UPDATE"); assert_variant(EventType::WebhooksUpdate, "WEBHOOKS_UPDATE"); + assert_variant(EventType::EntitlementCreate, "ENTITLEMENT_CREATE"); } } diff --git a/twilight-model/src/gateway/event/mod.rs b/twilight-model/src/gateway/event/mod.rs index 9f39711a2fa..dab89c8a60a 100644 --- a/twilight-model/src/gateway/event/mod.rs +++ b/twilight-model/src/gateway/event/mod.rs @@ -46,6 +46,8 @@ pub enum Event { ChannelUpdate(Box), /// A command's permissions were updated. CommandPermissionsUpdate(CommandPermissionsUpdate), + /// A user subscribes to a SKU. + EntitlementCreate(EntitlementCreate), /// Close message with an optional frame including information about the /// reason for the close. GatewayClose(Option>), @@ -237,6 +239,7 @@ impl Event { Event::VoiceStateUpdate(e) => e.0.guild_id, Event::WebhooksUpdate(e) => Some(e.guild_id), Event::GatewayClose(_) + | Event::EntitlementCreate(_) | Event::GatewayHeartbeat(_) | Event::GatewayHeartbeatAck | Event::GatewayHello(_) @@ -263,6 +266,7 @@ impl Event { Self::ChannelPinsUpdate(_) => EventType::ChannelPinsUpdate, Self::ChannelUpdate(_) => EventType::ChannelUpdate, Self::CommandPermissionsUpdate(_) => EventType::CommandPermissionsUpdate, + Self::EntitlementCreate(_) => EventType::EntitlementCreate, Self::GatewayClose(_) => EventType::GatewayClose, Self::GatewayHeartbeat(_) => EventType::GatewayHeartbeat, Self::GatewayHeartbeatAck => EventType::GatewayHeartbeatAck, @@ -342,6 +346,7 @@ impl From for Event { DispatchEvent::ChannelPinsUpdate(v) => Self::ChannelPinsUpdate(v), DispatchEvent::ChannelUpdate(v) => Self::ChannelUpdate(v), DispatchEvent::CommandPermissionsUpdate(v) => Self::CommandPermissionsUpdate(v), + DispatchEvent::EntitlementCreate(v) => Self::EntitlementCreate(v), DispatchEvent::GiftCodeUpdate => Self::GiftCodeUpdate, DispatchEvent::GuildAuditLogEntryCreate(v) => Self::GuildAuditLogEntryCreate(v), DispatchEvent::GuildCreate(v) => Self::GuildCreate(v), diff --git a/twilight-model/src/gateway/payload/incoming/entitlement_create.rs b/twilight-model/src/gateway/payload/incoming/entitlement_create.rs new file mode 100644 index 00000000000..ebc45593d53 --- /dev/null +++ b/twilight-model/src/gateway/payload/incoming/entitlement_create.rs @@ -0,0 +1,20 @@ +use crate::application::monetization::Entitlement; +use serde::{Deserialize, Serialize}; +use std::ops::{Deref, DerefMut}; + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct EntitlementCreate(pub Entitlement); + +impl Deref for EntitlementCreate { + type Target = Entitlement; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for EntitlementCreate { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/twilight-model/src/gateway/payload/incoming/mod.rs b/twilight-model/src/gateway/payload/incoming/mod.rs index a89f3683421..c2a7461a5f0 100644 --- a/twilight-model/src/gateway/payload/incoming/mod.rs +++ b/twilight-model/src/gateway/payload/incoming/mod.rs @@ -25,6 +25,7 @@ mod channel_delete; mod channel_pins_update; mod channel_update; mod command_permissions_update; +mod entitlement_create; mod guild_audit_log_entry_create; mod guild_create; mod guild_delete; @@ -82,7 +83,7 @@ pub use self::{ auto_moderation_rule_update::AutoModerationRuleUpdate, ban_add::BanAdd, ban_remove::BanRemove, channel_create::ChannelCreate, channel_delete::ChannelDelete, channel_pins_update::ChannelPinsUpdate, channel_update::ChannelUpdate, - command_permissions_update::CommandPermissionsUpdate, + command_permissions_update::CommandPermissionsUpdate, entitlement_create::EntitlementCreate, guild_audit_log_entry_create::GuildAuditLogEntryCreate, guild_create::GuildCreate, guild_delete::GuildDelete, guild_emojis_update::GuildEmojisUpdate, guild_integrations_update::GuildIntegrationsUpdate, From bab4c79bb00eda70e6d12dc21127e40d18dced36 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 23:05:02 -0400 Subject: [PATCH 07/21] entitlement update event --- twilight-cache-inmemory/src/lib.rs | 1 + twilight-gateway/src/event.rs | 3 +++ twilight-model/src/gateway/event/dispatch.rs | 2 ++ twilight-model/src/gateway/event/kind.rs | 2 ++ twilight-model/src/gateway/event/mod.rs | 9 +++++++++ .../payload/incoming/entitlement_update.rs | 20 +++++++++++++++++++ .../src/gateway/payload/incoming/mod.rs | 5 +++-- 7 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 twilight-model/src/gateway/payload/incoming/entitlement_update.rs diff --git a/twilight-cache-inmemory/src/lib.rs b/twilight-cache-inmemory/src/lib.rs index e9c2b58bafc..680fc0741ed 100644 --- a/twilight-cache-inmemory/src/lib.rs +++ b/twilight-cache-inmemory/src/lib.rs @@ -900,6 +900,7 @@ impl UpdateCache for Event { | Event::BanRemove(_) | Event::CommandPermissionsUpdate(_) | Event::EntitlementCreate(_) + | Event::EntitlementUpdate(_) | Event::GatewayClose(_) | Event::GatewayHeartbeat(_) | Event::GatewayHeartbeatAck diff --git a/twilight-gateway/src/event.rs b/twilight-gateway/src/event.rs index 38ef0ad6c3d..9638072f504 100644 --- a/twilight-gateway/src/event.rs +++ b/twilight-gateway/src/event.rs @@ -52,6 +52,8 @@ bitflags! { const AUTO_MODERATION_RULE_UPDATE = 1 << 74; /// An entitlement has been created. const ENTITLEMENT_CREATE = 1 << 76; + /// An entitlement has been updated. + const ENTITLEMENT_UPDATE = 1 << 77; /// User has been banned from a guild. const BAN_ADD = 1; /// User has been unbanned from a guild. @@ -343,6 +345,7 @@ impl From for EventTypeFlags { EventType::ChannelUpdate => Self::CHANNEL_UPDATE, EventType::CommandPermissionsUpdate => Self::COMMAND_PERMISSIONS_UPDATE, EventType::EntitlementCreate => Self::ENTITLEMENT_CREATE, + EventType::EntitlementUpdate => Self::ENTITLEMENT_UPDATE, EventType::GatewayClose => Self::empty(), EventType::GatewayHeartbeat => Self::GATEWAY_HEARTBEAT, EventType::GatewayHeartbeatAck => Self::GATEWAY_HEARTBEAT_ACK, diff --git a/twilight-model/src/gateway/event/dispatch.rs b/twilight-model/src/gateway/event/dispatch.rs index 121440010dc..c07a601a7a2 100644 --- a/twilight-model/src/gateway/event/dispatch.rs +++ b/twilight-model/src/gateway/event/dispatch.rs @@ -26,6 +26,7 @@ pub enum DispatchEvent { ChannelUpdate(Box), CommandPermissionsUpdate(CommandPermissionsUpdate), EntitlementCreate(EntitlementCreate), + EntitlementUpdate(EntitlementUpdate), GiftCodeUpdate, GuildAuditLogEntryCreate(Box), GuildCreate(Box), @@ -97,6 +98,7 @@ impl DispatchEvent { Self::ChannelUpdate(_) => EventType::ChannelUpdate, Self::CommandPermissionsUpdate(_) => EventType::CommandPermissionsUpdate, Self::EntitlementCreate(_) => EventType::EntitlementCreate, + Self::EntitlementUpdate(_) => EventType::EntitlementUpdate, Self::GiftCodeUpdate => EventType::GiftCodeUpdate, Self::GuildAuditLogEntryCreate(_) => EventType::GuildAuditLogEntryCreate, Self::GuildCreate(_) => EventType::GuildCreate, diff --git a/twilight-model/src/gateway/event/kind.rs b/twilight-model/src/gateway/event/kind.rs index eca5b3042ba..70dc3f9dbf6 100644 --- a/twilight-model/src/gateway/event/kind.rs +++ b/twilight-model/src/gateway/event/kind.rs @@ -19,6 +19,7 @@ pub enum EventType { #[serde(rename = "APPLICATION_COMMAND_PERMISSIONS_UPDATE")] CommandPermissionsUpdate, EntitlementCreate, + EntitlementUpdate, GatewayClose, GatewayHeartbeat, GatewayHeartbeatAck, @@ -106,6 +107,7 @@ impl EventType { Self::ChannelUpdate => Some("CHANNEL_UPDATE"), Self::CommandPermissionsUpdate => Some("APPLICATION_COMMAND_PERMISSIONS_UPDATE"), Self::EntitlementCreate => Some("ENTITLEMENT_CREATE"), + Self::EntitlementUpdate => Some("ENTITLEMENT_UPDATE"), Self::GiftCodeUpdate => Some("GIFT_CODE_UPDATE"), Self::GuildAuditLogEntryCreate => Some("GUILD_AUDIT_LOG_ENTRY_CREATE"), Self::GuildCreate => Some("GUILD_CREATE"), diff --git a/twilight-model/src/gateway/event/mod.rs b/twilight-model/src/gateway/event/mod.rs index dab89c8a60a..91f26472a77 100644 --- a/twilight-model/src/gateway/event/mod.rs +++ b/twilight-model/src/gateway/event/mod.rs @@ -48,6 +48,12 @@ pub enum Event { CommandPermissionsUpdate(CommandPermissionsUpdate), /// A user subscribes to a SKU. EntitlementCreate(EntitlementCreate), + /// Fires when a user's subscription renews for the + /// next billing period. + /// + /// The `ends_at` field will have an updated value with + /// the new expiration date. + EntitlementUpdate(EntitlementUpdate), /// Close message with an optional frame including information about the /// reason for the close. GatewayClose(Option>), @@ -240,6 +246,7 @@ impl Event { Event::WebhooksUpdate(e) => Some(e.guild_id), Event::GatewayClose(_) | Event::EntitlementCreate(_) + | Event::EntitlementUpdate(_) | Event::GatewayHeartbeat(_) | Event::GatewayHeartbeatAck | Event::GatewayHello(_) @@ -267,6 +274,7 @@ impl Event { Self::ChannelUpdate(_) => EventType::ChannelUpdate, Self::CommandPermissionsUpdate(_) => EventType::CommandPermissionsUpdate, Self::EntitlementCreate(_) => EventType::EntitlementCreate, + Self::EntitlementUpdate(_) => EventType::EntitlementUpdate, Self::GatewayClose(_) => EventType::GatewayClose, Self::GatewayHeartbeat(_) => EventType::GatewayHeartbeat, Self::GatewayHeartbeatAck => EventType::GatewayHeartbeatAck, @@ -347,6 +355,7 @@ impl From for Event { DispatchEvent::ChannelUpdate(v) => Self::ChannelUpdate(v), DispatchEvent::CommandPermissionsUpdate(v) => Self::CommandPermissionsUpdate(v), DispatchEvent::EntitlementCreate(v) => Self::EntitlementCreate(v), + DispatchEvent::EntitlementUpdate(v) => Self::EntitlementUpdate(v), DispatchEvent::GiftCodeUpdate => Self::GiftCodeUpdate, DispatchEvent::GuildAuditLogEntryCreate(v) => Self::GuildAuditLogEntryCreate(v), DispatchEvent::GuildCreate(v) => Self::GuildCreate(v), diff --git a/twilight-model/src/gateway/payload/incoming/entitlement_update.rs b/twilight-model/src/gateway/payload/incoming/entitlement_update.rs new file mode 100644 index 00000000000..3e180edd901 --- /dev/null +++ b/twilight-model/src/gateway/payload/incoming/entitlement_update.rs @@ -0,0 +1,20 @@ +use crate::application::monetization::Entitlement; +use serde::{Deserialize, Serialize}; +use std::ops::{Deref, DerefMut}; + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct EntitlementUpdate(pub Entitlement); + +impl Deref for EntitlementUpdate { + type Target = Entitlement; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for EntitlementUpdate { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/twilight-model/src/gateway/payload/incoming/mod.rs b/twilight-model/src/gateway/payload/incoming/mod.rs index c2a7461a5f0..b7186e1a00b 100644 --- a/twilight-model/src/gateway/payload/incoming/mod.rs +++ b/twilight-model/src/gateway/payload/incoming/mod.rs @@ -26,6 +26,7 @@ mod channel_pins_update; mod channel_update; mod command_permissions_update; mod entitlement_create; +mod entitlement_update; mod guild_audit_log_entry_create; mod guild_create; mod guild_delete; @@ -84,8 +85,8 @@ pub use self::{ channel_create::ChannelCreate, channel_delete::ChannelDelete, channel_pins_update::ChannelPinsUpdate, channel_update::ChannelUpdate, command_permissions_update::CommandPermissionsUpdate, entitlement_create::EntitlementCreate, - guild_audit_log_entry_create::GuildAuditLogEntryCreate, guild_create::GuildCreate, - guild_delete::GuildDelete, guild_emojis_update::GuildEmojisUpdate, + entitlement_update::EntitlementUpdate, guild_audit_log_entry_create::GuildAuditLogEntryCreate, + guild_create::GuildCreate, guild_delete::GuildDelete, guild_emojis_update::GuildEmojisUpdate, guild_integrations_update::GuildIntegrationsUpdate, guild_scheduled_event_create::GuildScheduledEventCreate, guild_scheduled_event_delete::GuildScheduledEventDelete, From 02141c457d8e211017ca5b6cea3d57cc9ec415ce Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 23:14:48 -0400 Subject: [PATCH 08/21] entitlement delete event --- twilight-cache-inmemory/src/lib.rs | 1 + twilight-gateway/src/event.rs | 5 ++++- twilight-model/src/gateway/event/dispatch.rs | 2 ++ twilight-model/src/gateway/event/kind.rs | 2 ++ twilight-model/src/gateway/event/mod.rs | 7 ++++++- .../payload/incoming/entitlement_delete.rs | 20 +++++++++++++++++++ .../src/gateway/payload/incoming/mod.rs | 6 ++++-- 7 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 twilight-model/src/gateway/payload/incoming/entitlement_delete.rs diff --git a/twilight-cache-inmemory/src/lib.rs b/twilight-cache-inmemory/src/lib.rs index 680fc0741ed..8497dc8cf98 100644 --- a/twilight-cache-inmemory/src/lib.rs +++ b/twilight-cache-inmemory/src/lib.rs @@ -900,6 +900,7 @@ impl UpdateCache for Event { | Event::BanRemove(_) | Event::CommandPermissionsUpdate(_) | Event::EntitlementCreate(_) + | Event::EntitlementDelete(_) | Event::EntitlementUpdate(_) | Event::GatewayClose(_) | Event::GatewayHeartbeat(_) diff --git a/twilight-gateway/src/event.rs b/twilight-gateway/src/event.rs index 9638072f504..07c1244ee94 100644 --- a/twilight-gateway/src/event.rs +++ b/twilight-gateway/src/event.rs @@ -52,8 +52,10 @@ bitflags! { const AUTO_MODERATION_RULE_UPDATE = 1 << 74; /// An entitlement has been created. const ENTITLEMENT_CREATE = 1 << 76; + /// An entitlement has been deleted. + const ENTITLEMENT_DELETE = 1 << 77; /// An entitlement has been updated. - const ENTITLEMENT_UPDATE = 1 << 77; + const ENTITLEMENT_UPDATE = 1 << 78; /// User has been banned from a guild. const BAN_ADD = 1; /// User has been unbanned from a guild. @@ -345,6 +347,7 @@ impl From for EventTypeFlags { EventType::ChannelUpdate => Self::CHANNEL_UPDATE, EventType::CommandPermissionsUpdate => Self::COMMAND_PERMISSIONS_UPDATE, EventType::EntitlementCreate => Self::ENTITLEMENT_CREATE, + EventType::EntitlementDelete => Self::ENTITLEMENT_DELETE, EventType::EntitlementUpdate => Self::ENTITLEMENT_UPDATE, EventType::GatewayClose => Self::empty(), EventType::GatewayHeartbeat => Self::GATEWAY_HEARTBEAT, diff --git a/twilight-model/src/gateway/event/dispatch.rs b/twilight-model/src/gateway/event/dispatch.rs index c07a601a7a2..5cc5d7b1f70 100644 --- a/twilight-model/src/gateway/event/dispatch.rs +++ b/twilight-model/src/gateway/event/dispatch.rs @@ -26,6 +26,7 @@ pub enum DispatchEvent { ChannelUpdate(Box), CommandPermissionsUpdate(CommandPermissionsUpdate), EntitlementCreate(EntitlementCreate), + EntitlementDelete(EntitlementDelete), EntitlementUpdate(EntitlementUpdate), GiftCodeUpdate, GuildAuditLogEntryCreate(Box), @@ -98,6 +99,7 @@ impl DispatchEvent { Self::ChannelUpdate(_) => EventType::ChannelUpdate, Self::CommandPermissionsUpdate(_) => EventType::CommandPermissionsUpdate, Self::EntitlementCreate(_) => EventType::EntitlementCreate, + Self::EntitlementDelete(_) => EventType::EntitlementDelete, Self::EntitlementUpdate(_) => EventType::EntitlementUpdate, Self::GiftCodeUpdate => EventType::GiftCodeUpdate, Self::GuildAuditLogEntryCreate(_) => EventType::GuildAuditLogEntryCreate, diff --git a/twilight-model/src/gateway/event/kind.rs b/twilight-model/src/gateway/event/kind.rs index 70dc3f9dbf6..7fa189cde2a 100644 --- a/twilight-model/src/gateway/event/kind.rs +++ b/twilight-model/src/gateway/event/kind.rs @@ -19,6 +19,7 @@ pub enum EventType { #[serde(rename = "APPLICATION_COMMAND_PERMISSIONS_UPDATE")] CommandPermissionsUpdate, EntitlementCreate, + EntitlementDelete, EntitlementUpdate, GatewayClose, GatewayHeartbeat, @@ -107,6 +108,7 @@ impl EventType { Self::ChannelUpdate => Some("CHANNEL_UPDATE"), Self::CommandPermissionsUpdate => Some("APPLICATION_COMMAND_PERMISSIONS_UPDATE"), Self::EntitlementCreate => Some("ENTITLEMENT_CREATE"), + Self::EntitlementDelete => Some("ENTITLEMENT_DELETE"), Self::EntitlementUpdate => Some("ENTITLEMENT_UPDATE"), Self::GiftCodeUpdate => Some("GIFT_CODE_UPDATE"), Self::GuildAuditLogEntryCreate => Some("GUILD_AUDIT_LOG_ENTRY_CREATE"), diff --git a/twilight-model/src/gateway/event/mod.rs b/twilight-model/src/gateway/event/mod.rs index 91f26472a77..dd31814251a 100644 --- a/twilight-model/src/gateway/event/mod.rs +++ b/twilight-model/src/gateway/event/mod.rs @@ -48,7 +48,9 @@ pub enum Event { CommandPermissionsUpdate(CommandPermissionsUpdate), /// A user subscribes to a SKU. EntitlementCreate(EntitlementCreate), - /// Fires when a user's subscription renews for the + /// A user's entitlement is removed. + EntitlementDelete(EntitlementDelete), + /// A user's subscription renews for the /// next billing period. /// /// The `ends_at` field will have an updated value with @@ -246,6 +248,7 @@ impl Event { Event::WebhooksUpdate(e) => Some(e.guild_id), Event::GatewayClose(_) | Event::EntitlementCreate(_) + | Event::EntitlementDelete(_) | Event::EntitlementUpdate(_) | Event::GatewayHeartbeat(_) | Event::GatewayHeartbeatAck @@ -274,6 +277,7 @@ impl Event { Self::ChannelUpdate(_) => EventType::ChannelUpdate, Self::CommandPermissionsUpdate(_) => EventType::CommandPermissionsUpdate, Self::EntitlementCreate(_) => EventType::EntitlementCreate, + Self::EntitlementDelete(_) => EventType::EntitlementDelete, Self::EntitlementUpdate(_) => EventType::EntitlementUpdate, Self::GatewayClose(_) => EventType::GatewayClose, Self::GatewayHeartbeat(_) => EventType::GatewayHeartbeat, @@ -355,6 +359,7 @@ impl From for Event { DispatchEvent::ChannelUpdate(v) => Self::ChannelUpdate(v), DispatchEvent::CommandPermissionsUpdate(v) => Self::CommandPermissionsUpdate(v), DispatchEvent::EntitlementCreate(v) => Self::EntitlementCreate(v), + DispatchEvent::EntitlementDelete(v) => Self::EntitlementDelete(v), DispatchEvent::EntitlementUpdate(v) => Self::EntitlementUpdate(v), DispatchEvent::GiftCodeUpdate => Self::GiftCodeUpdate, DispatchEvent::GuildAuditLogEntryCreate(v) => Self::GuildAuditLogEntryCreate(v), diff --git a/twilight-model/src/gateway/payload/incoming/entitlement_delete.rs b/twilight-model/src/gateway/payload/incoming/entitlement_delete.rs new file mode 100644 index 00000000000..dd4d5ed2c36 --- /dev/null +++ b/twilight-model/src/gateway/payload/incoming/entitlement_delete.rs @@ -0,0 +1,20 @@ +use crate::application::monetization::Entitlement; +use serde::{Deserialize, Serialize}; +use std::ops::{Deref, DerefMut}; + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub struct EntitlementDelete(pub Entitlement); + +impl Deref for EntitlementDelete { + type Target = Entitlement; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for EntitlementDelete { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/twilight-model/src/gateway/payload/incoming/mod.rs b/twilight-model/src/gateway/payload/incoming/mod.rs index b7186e1a00b..b99b4cf1d00 100644 --- a/twilight-model/src/gateway/payload/incoming/mod.rs +++ b/twilight-model/src/gateway/payload/incoming/mod.rs @@ -26,6 +26,7 @@ mod channel_pins_update; mod channel_update; mod command_permissions_update; mod entitlement_create; +mod entitlement_delete; mod entitlement_update; mod guild_audit_log_entry_create; mod guild_create; @@ -85,8 +86,9 @@ pub use self::{ channel_create::ChannelCreate, channel_delete::ChannelDelete, channel_pins_update::ChannelPinsUpdate, channel_update::ChannelUpdate, command_permissions_update::CommandPermissionsUpdate, entitlement_create::EntitlementCreate, - entitlement_update::EntitlementUpdate, guild_audit_log_entry_create::GuildAuditLogEntryCreate, - guild_create::GuildCreate, guild_delete::GuildDelete, guild_emojis_update::GuildEmojisUpdate, + entitlement_delete::EntitlementDelete, entitlement_update::EntitlementUpdate, + guild_audit_log_entry_create::GuildAuditLogEntryCreate, guild_create::GuildCreate, + guild_delete::GuildDelete, guild_emojis_update::GuildEmojisUpdate, guild_integrations_update::GuildIntegrationsUpdate, guild_scheduled_event_create::GuildScheduledEventCreate, guild_scheduled_event_delete::GuildScheduledEventDelete, From 4992b3d2992f7f7791f6da02c1264265d94a4e15 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 23:34:56 -0400 Subject: [PATCH 09/21] update interactions to support premium apps --- .../src/application/interaction/mod.rs | 61 ++++++++++++++++++- .../application/monetization/entitlement.rs | 18 +++--- twilight-model/src/http/interaction.rs | 3 + 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/twilight-model/src/application/interaction/mod.rs b/twilight-model/src/application/interaction/mod.rs index 2353f17e5b4..84c26d03fcb 100644 --- a/twilight-model/src/application/interaction/mod.rs +++ b/twilight-model/src/application/interaction/mod.rs @@ -32,6 +32,8 @@ use serde::{ use serde_value::{DeserializerError, Value}; use std::fmt::{Formatter, Result as FmtResult}; +use super::monetization::Entitlement; + /// Payload received when a user executes an interaction. /// /// See [Discord Docs/Interaction Object]. @@ -75,6 +77,8 @@ pub struct Interaction { /// [`ModalSubmit`]: InteractionType::ModalSubmit #[serde(skip_serializing_if = "Option::is_none")] pub data: Option, + /// For monetized apps, any entitlements for the invoking user, representing access to premium SKUs + pub entitlements: Vec, /// ID of the guild the interaction was invoked in. #[serde(skip_serializing_if = "Option::is_none")] pub guild_id: Option>, @@ -173,6 +177,7 @@ enum InteractionField { Channel, ChannelId, Data, + Entitlements, GuildId, GuildLocale, Id, @@ -201,6 +206,7 @@ impl<'de> Visitor<'de> for InteractionVisitor { let mut channel: Option = None; let mut channel_id: Option> = None; let mut data: Option = None; + let mut entitlements: Vec = Vec::new(); let mut guild_id: Option> = None; let mut guild_locale: Option = None; let mut id: Option> = None; @@ -258,6 +264,13 @@ impl<'de> Visitor<'de> for InteractionVisitor { data = map.next_value()?; } + InteractionField::Entitlements => { + if data.is_some() { + return Err(DeError::duplicate_field("entitlements")); + } + + entitlements = map.next_value()?; + } InteractionField::GuildId => { if guild_id.is_some() { return Err(DeError::duplicate_field("guild_id")); @@ -376,6 +389,7 @@ impl<'de> Visitor<'de> for InteractionVisitor { channel, channel_id, data, + entitlements, guild_id, guild_locale, id, @@ -420,7 +434,10 @@ mod tests { Interaction, InteractionData, InteractionType, }; use crate::{ - application::command::{CommandOptionType, CommandType}, + application::{ + command::{CommandOptionType, CommandType}, + monetization::{entitlement::Entitlement, EntitlementType}, + }, channel::Channel, guild::{MemberFlags, PartialMember, Permissions}, id::Id, @@ -533,6 +550,17 @@ mod tests { }), target_id: None, }))), + entitlements: Vec::from([Entitlement { + application_id: Id::new(100), + consumed: false, + ends_at: None, + guild_id: None, + id: Id::new(200), + kind: EntitlementType::ApplicationSubscription, + sku_id: Id::new(300), + starts_at: None, + user_id: None, + }]), guild_id: Some(Id::new(400)), guild_locale: Some("de".to_owned()), id: Id::new(500), @@ -580,7 +608,7 @@ mod tests { &[ Token::Struct { name: "Interaction", - len: 12, + len: 13, }, Token::Str("app_permissions"), Token::Some, @@ -697,6 +725,35 @@ mod tests { Token::MapEnd, Token::StructEnd, Token::StructEnd, + Token::Str("entitlements"), + Token::Seq { len: Some(1) }, + Token::Struct { + name: "Entitlement", + len: 9, + }, + Token::Str("application_id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("100"), + Token::Str("consumed"), + Token::Bool(false), + Token::Str("ends_at"), + Token::None, + Token::Str("guild_id"), + Token::None, + Token::Str("id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("200"), + Token::Str("type"), + Token::U8(8), + Token::Str("sku_id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("300"), + Token::Str("starts_at"), + Token::None, + Token::Str("user_id"), + Token::None, + Token::StructEnd, + Token::SeqEnd, Token::Str("guild_id"), Token::Some, Token::NewtypeStruct { name: "Id" }, diff --git a/twilight-model/src/application/monetization/entitlement.rs b/twilight-model/src/application/monetization/entitlement.rs index cc4b8c5c0b1..7d04605b1e4 100644 --- a/twilight-model/src/application/monetization/entitlement.rs +++ b/twilight-model/src/application/monetization/entitlement.rs @@ -16,24 +16,24 @@ use super::entitlement_type::EntitlementType; #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] pub struct Entitlement { /// ID of the parent application. - application_id: Id, + pub application_id: Id, /// Not applicable for App Subscriptions. Subscriptions are not consumed and will be `false` - consumed: bool, + pub consumed: bool, /// Date at which the entitlement is no longer valid. Not present when using test entitlements. - ends_at: Option, + pub ends_at: Option, /// ID of the guild that is granted access to the entitlement's sku. - guild_id: Option>, + pub guild_id: Option>, /// ID of the entitlement. - id: Id, + pub id: Id, /// Type of entitlement. #[serde(rename = "type")] - kind: EntitlementType, + pub kind: EntitlementType, /// ID of the SKU. - sku_id: Id, + pub sku_id: Id, /// Start date at which the entitlement is valid. Not present when using test entitlements. - starts_at: Option, + pub starts_at: Option, /// ID of the user that is granted access to the entitlement's sku. - user_id: Option>, + pub user_id: Option>, } #[cfg(test)] diff --git a/twilight-model/src/http/interaction.rs b/twilight-model/src/http/interaction.rs index ce05c35bbc9..f2357d087c8 100644 --- a/twilight-model/src/http/interaction.rs +++ b/twilight-model/src/http/interaction.rs @@ -100,6 +100,9 @@ pub enum InteractionResponseType { ApplicationCommandAutocompleteResult = 8, /// Respond to an interaction with a popup modal. Modal = 9, + /// Respond to an interaction with an upgrade button, only available + /// for apps with monetization enabled + PremiumRequired = 10, } #[cfg(test)] From faaea85020dd45eb407ae0126211bc0044ca70d3 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 23:42:04 -0400 Subject: [PATCH 10/21] update interaction caching --- twilight-cache-inmemory/src/event/interaction.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/twilight-cache-inmemory/src/event/interaction.rs b/twilight-cache-inmemory/src/event/interaction.rs index b08b25ebdce..3292b7049f3 100644 --- a/twilight-cache-inmemory/src/event/interaction.rs +++ b/twilight-cache-inmemory/src/event/interaction.rs @@ -271,6 +271,7 @@ mod tests { }), target_id: None, }))), + entitlements: Vec::new(), guild_id: Some(Id::new(3)), guild_locale: None, id: Id::new(4), From 73410c03581fda8d9ffe576e4bee9062daec2813 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 23:45:09 -0400 Subject: [PATCH 11/21] update standby --- twilight-standby/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/twilight-standby/src/lib.rs b/twilight-standby/src/lib.rs index d52a6bae3e2..c2201e4ab25 100644 --- a/twilight-standby/src/lib.rs +++ b/twilight-standby/src/lib.rs @@ -1204,6 +1204,7 @@ mod tests { values: Vec::new(), }, )), + entitlements: Vec::new(), guild_id: Some(Id::new(3)), guild_locale: None, id: Id::new(4), From ff275318898e5e941ef7ba111a81c77b008b76f4 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Wed, 27 Sep 2023 23:53:50 -0400 Subject: [PATCH 12/21] fix doc import --- twilight-http/src/client/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index 05a653f326b..36654700704 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -2586,7 +2586,7 @@ impl Client { /// # Examples /// /// ```no_run - /// use twilight_http::{Client, request::application::entitlement::CreateTestEntitlementOwner}; + /// use twilight_http::{Client, request::application::monetization::CreateTestEntitlementOwner}; /// use twilight_model::id::Id; /// /// # #[tokio::main] From fdfec122b0b28c9f1dc01ae9f69494decdfe682b Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Thu, 28 Sep 2023 15:26:07 -0400 Subject: [PATCH 13/21] add SKU structure --- twilight-http/src/client/mod.rs | 6 +- .../monetization/create_test_entitlement.rs | 6 +- .../monetization/get_entitlements.rs | 8 +- twilight-http/src/routing.rs | 4 +- .../application/monetization/entitlement.rs | 6 +- .../src/application/monetization/mod.rs | 8 +- .../src/application/monetization/sku.rs | 73 ++++++++++++++ .../src/application/monetization/sku_flags.rs | 94 +++++++++++++++++++ .../src/application/monetization/sku_type.rs | 41 ++++++++ twilight-model/src/id/marker.rs | 6 +- twilight-model/src/id/mod.rs | 12 +-- 11 files changed, 237 insertions(+), 27 deletions(-) create mode 100644 twilight-model/src/application/monetization/sku.rs create mode 100644 twilight-model/src/application/monetization/sku_flags.rs create mode 100644 twilight-model/src/application/monetization/sku_type.rs diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index 36654700704..b3089ee95a6 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -113,8 +113,8 @@ use twilight_model::{ id::{ marker::{ ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker, - EntitlementMarker, EntitlementSkuMarker, GuildMarker, IntegrationMarker, MessageMarker, - RoleMarker, ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, + EntitlementMarker, GuildMarker, IntegrationMarker, MessageMarker, RoleMarker, + SKUMarker, ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, }, Id, }, @@ -2607,7 +2607,7 @@ impl Client { pub const fn create_test_entitlement( &self, application_id: Id, - sku_id: Id, + sku_id: Id, owner: CreateTestEntitlementOwner, ) -> CreateTestEntitlement<'_> { CreateTestEntitlement::new(self, application_id, sku_id, owner) diff --git a/twilight-http/src/request/application/monetization/create_test_entitlement.rs b/twilight-http/src/request/application/monetization/create_test_entitlement.rs index dddce516729..f8f0ccb75bb 100644 --- a/twilight-http/src/request/application/monetization/create_test_entitlement.rs +++ b/twilight-http/src/request/application/monetization/create_test_entitlement.rs @@ -4,7 +4,7 @@ use serde::ser::{Serialize, SerializeStruct, Serializer}; use twilight_model::{ application::monetization::Entitlement, id::{ - marker::{ApplicationMarker, EntitlementSkuMarker, GuildMarker, UserMarker}, + marker::{ApplicationMarker, GuildMarker, SKUMarker, UserMarker}, Id, }, }; @@ -39,7 +39,7 @@ impl CreateTestEntitlementOwner { } struct CreateTestEntitlementFields { - sku_id: Id, + sku_id: Id, owner: CreateTestEntitlementOwner, } @@ -66,7 +66,7 @@ impl<'a> CreateTestEntitlement<'a> { pub(crate) const fn new( http: &'a Client, application_id: Id, - sku_id: Id, + sku_id: Id, owner: CreateTestEntitlementOwner, ) -> Self { Self { diff --git a/twilight-http/src/request/application/monetization/get_entitlements.rs b/twilight-http/src/request/application/monetization/get_entitlements.rs index 83c43842889..df938579588 100644 --- a/twilight-http/src/request/application/monetization/get_entitlements.rs +++ b/twilight-http/src/request/application/monetization/get_entitlements.rs @@ -3,9 +3,7 @@ use std::future::IntoFuture; use twilight_model::{ application::monetization::Entitlement, id::{ - marker::{ - ApplicationMarker, EntitlementMarker, EntitlementSkuMarker, GuildMarker, UserMarker, - }, + marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SKUMarker, UserMarker}, Id, }, }; @@ -27,7 +25,7 @@ struct GetEntitlementsFields<'a> { exclude_ended: Option, guild_id: Option>, limit: Option, - sku_ids: &'a [Id], + sku_ids: &'a [Id], user_id: Option>, } @@ -105,7 +103,7 @@ impl<'a> GetEntitlements<'a> { } /// List of SKU IDs to check entitlements for. - pub const fn sku_ids(mut self, sku_ids: &'a [Id]) -> Self { + pub const fn sku_ids(mut self, sku_ids: &'a [Id]) -> Self { self.fields.sku_ids = sku_ids; self diff --git a/twilight-http/src/routing.rs b/twilight-http/src/routing.rs index 06970038df0..6612a13e35e 100644 --- a/twilight-http/src/routing.rs +++ b/twilight-http/src/routing.rs @@ -4,7 +4,7 @@ pub use twilight_http_ratelimiting::request::{Path, PathParseError, PathParseErr use crate::request::{channel::reaction::RequestReactionType, Method}; use std::fmt::{Display, Formatter, Result as FmtResult}; use twilight_model::id::{ - marker::{EntitlementSkuMarker, RoleMarker}, + marker::{RoleMarker, SKUMarker}, Id, }; @@ -480,7 +480,7 @@ pub enum Route<'a> { /// Number of entitlements to return. Set to 100 if unspecified. limit: Option, /// List of SKU IDs to check entitlements for. - sku_ids: &'a [Id], + sku_ids: &'a [Id], /// User ID to look up entitlements for. user_id: Option, }, diff --git a/twilight-model/src/application/monetization/entitlement.rs b/twilight-model/src/application/monetization/entitlement.rs index 7d04605b1e4..f8101d66bf9 100644 --- a/twilight-model/src/application/monetization/entitlement.rs +++ b/twilight-model/src/application/monetization/entitlement.rs @@ -2,9 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ id::{ - marker::{ - ApplicationMarker, EntitlementMarker, EntitlementSkuMarker, GuildMarker, UserMarker, - }, + marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SKUMarker, UserMarker}, Id, }, util::Timestamp, @@ -29,7 +27,7 @@ pub struct Entitlement { #[serde(rename = "type")] pub kind: EntitlementType, /// ID of the SKU. - pub sku_id: Id, + pub sku_id: Id, /// Start date at which the entitlement is valid. Not present when using test entitlements. pub starts_at: Option, /// ID of the user that is granted access to the entitlement's sku. diff --git a/twilight-model/src/application/monetization/mod.rs b/twilight-model/src/application/monetization/mod.rs index eb4caf25db7..92140e53f0d 100644 --- a/twilight-model/src/application/monetization/mod.rs +++ b/twilight-model/src/application/monetization/mod.rs @@ -1,4 +1,10 @@ pub mod entitlement; pub mod entitlement_type; +pub mod sku; +pub mod sku_flags; +pub mod sku_type; -pub use self::{entitlement::Entitlement, entitlement_type::EntitlementType}; +pub use self::{ + entitlement::Entitlement, entitlement_type::EntitlementType, sku::SKU, sku_flags::SKUFlags, + sku_type::SKUType, +}; diff --git a/twilight-model/src/application/monetization/sku.rs b/twilight-model/src/application/monetization/sku.rs new file mode 100644 index 00000000000..5439de89916 --- /dev/null +++ b/twilight-model/src/application/monetization/sku.rs @@ -0,0 +1,73 @@ +use serde::{Deserialize, Serialize}; + +use crate::id::{ + marker::{ApplicationMarker, SKUMarker}, + Id, +}; + +use super::{SKUFlags, SKUType}; + +/// SKUs (stock-keeping units) in Discord represent premium offerings that can be made available to your application's users or guilds. +#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] +pub struct SKU { + /// ID of SKU. + id: Id, + /// Type of SKU. + #[serde(rename = "type")] + kind: SKUType, + /// ID of the parent application. + application_id: Id, + /// Customer-facing name of your premium offering. + name: String, + /// System-generated URL slug based on the SKU's name. + slug: String, + /// Flags for the SKU. + flags: SKUFlags, +} + +#[cfg(test)] +mod tests { + use serde_test::Token; + + use crate::{ + application::monetization::{SKUFlags, SKUType}, + id::Id, + }; + + use super::SKU; + + #[test] + fn sku() { + serde_test::assert_tokens( + &SKU { + id: Id::new(1), + kind: SKUType::Subscription, + application_id: Id::new(2), + name: "a name".to_owned(), + slug: "a-slug".to_owned(), + flags: SKUFlags::GUILD_SUBSCRIPTION, + }, + &[ + Token::Struct { + name: "SKU", + len: 6, + }, + Token::Str("id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("1"), + Token::Str("type"), + Token::U8(1), + Token::Str("application_id"), + Token::NewtypeStruct { name: "Id" }, + Token::Str("2"), + Token::Str("name"), + Token::Str("a name"), + Token::Str("slug"), + Token::Str("a-slug"), + Token::Str("flags"), + Token::U64(1 << 7), + Token::StructEnd, + ], + ); + } +} diff --git a/twilight-model/src/application/monetization/sku_flags.rs b/twilight-model/src/application/monetization/sku_flags.rs new file mode 100644 index 00000000000..54339a988b8 --- /dev/null +++ b/twilight-model/src/application/monetization/sku_flags.rs @@ -0,0 +1,94 @@ +use bitflags::bitflags; +use serde::{ + de::{Deserialize, Deserializer}, + ser::{Serialize, Serializer}, +}; + +bitflags! { + pub struct SKUFlags: u64 { + /// A subscription purchased by a user and applied to a single server. + /// Everyone in that server gets your premium benefits. + const GUILD_SUBSCRIPTION = 1 << 7; + /// A subscription purchased by a user for themselves. They get access + /// to your premium benefits in every server. + const USER_SUBSCRIPTION = 1 << 8; + } +} + +impl<'de> Deserialize<'de> for SKUFlags { + fn deserialize>(deserializer: D) -> Result { + Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) + } +} + +impl Serialize for SKUFlags { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_u64(self.bits()) + } +} + +#[cfg(test)] +mod tests { + use super::SKUFlags; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + SKUFlags: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + + const_assert_eq!(SKUFlags::GUILD_SUBSCRIPTION.bits(), 1 << 7); + const_assert_eq!(SKUFlags::USER_SUBSCRIPTION.bits(), 1 << 8); + + #[test] + fn serde() { + serde_test::assert_tokens( + &SKUFlags::GUILD_SUBSCRIPTION, + &[Token::U64(SKUFlags::GUILD_SUBSCRIPTION.bits())], + ); + + serde_test::assert_tokens( + &SKUFlags::USER_SUBSCRIPTION, + &[Token::U64(SKUFlags::USER_SUBSCRIPTION.bits())], + ); + + serde_test::assert_de_tokens(&SKUFlags::empty(), &[Token::U64(1 << 63)]); + } +} diff --git a/twilight-model/src/application/monetization/sku_type.rs b/twilight-model/src/application/monetization/sku_type.rs new file mode 100644 index 00000000000..726174b08bb --- /dev/null +++ b/twilight-model/src/application/monetization/sku_type.rs @@ -0,0 +1,41 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[serde(from = "u8", into = "u8")] +pub enum SKUType { + Subscription, + SubscriptionGroup, + Unknown(u8), +} + +impl From for SKUType { + fn from(value: u8) -> Self { + match value { + 1 => SKUType::Subscription, + 2 => SKUType::SubscriptionGroup, + other => SKUType::Unknown(other), + } + } +} + +impl From for u8 { + fn from(value: SKUType) -> Self { + match value { + SKUType::Subscription => 1, + SKUType::SubscriptionGroup => 2, + SKUType::Unknown(other) => other, + } + } +} + +#[cfg(test)] +mod tests { + use super::SKUType; + use serde_test::Token; + #[test] + fn sku_type() { + serde_test::assert_tokens(&SKUType::Subscription, &[Token::U8(1)]); + serde_test::assert_tokens(&SKUType::SubscriptionGroup, &[Token::U8(2)]); + serde_test::assert_tokens(&SKUType::Unknown(3), &[Token::U8(3)]); + } +} diff --git a/twilight-model/src/id/marker.rs b/twilight-model/src/id/marker.rs index cf6cc56de3b..662ffe110e3 100644 --- a/twilight-model/src/id/marker.rs +++ b/twilight-model/src/id/marker.rs @@ -96,12 +96,12 @@ pub struct EntitlementMarker; /// Marker for entitlement SKU IDs. /// -/// Types such as [`Entitlement`] use this ID marker. +/// Types such as [`SKU`] use this ID marker. /// -/// [`Entitlement`]: crate::application::monetization::entitlement::Entitlement +/// [`SKU`]: crate::application::monetization::sku::SKU #[derive(Debug)] #[non_exhaustive] -pub struct EntitlementSkuMarker; +pub struct SKUMarker; /// Marker for generic IDs. /// diff --git a/twilight-model/src/id/mod.rs b/twilight-model/src/id/mod.rs index 6044dd414d1..7d91e5c4764 100644 --- a/twilight-model/src/id/mod.rs +++ b/twilight-model/src/id/mod.rs @@ -418,9 +418,9 @@ mod tests { use super::{ marker::{ ApplicationMarker, AttachmentMarker, AuditLogEntryMarker, ChannelMarker, CommandMarker, - CommandVersionMarker, EmojiMarker, EntitlementMarker, EntitlementSkuMarker, - GenericMarker, GuildMarker, IntegrationMarker, InteractionMarker, MessageMarker, - RoleMarker, RoleSubscriptionSkuMarker, StageMarker, UserMarker, WebhookMarker, + CommandVersionMarker, EmojiMarker, EntitlementMarker, GenericMarker, GuildMarker, + IntegrationMarker, InteractionMarker, MessageMarker, RoleMarker, + RoleSubscriptionSkuMarker, SKUMarker, StageMarker, UserMarker, WebhookMarker, }, Id, }; @@ -444,7 +444,7 @@ mod tests { assert_impl_all!(CommandVersionMarker: Debug, Send, Sync); assert_impl_all!(EmojiMarker: Debug, Send, Sync); assert_impl_all!(EntitlementMarker: Debug, Send, Sync); - assert_impl_all!(EntitlementSkuMarker: Debug, Send, Sync); + assert_impl_all!(SKUMarker: Debug, Send, Sync); assert_impl_all!(GenericMarker: Debug, Send, Sync); assert_impl_all!(GuildMarker: Debug, Send, Sync); assert_impl_all!(IntegrationMarker: Debug, Send, Sync); @@ -678,14 +678,14 @@ mod tests { ], ); serde_test::assert_tokens( - &Id::::new(114_941_315_417_899_012), + &Id::::new(114_941_315_417_899_012), &[ Token::NewtypeStruct { name: "Id" }, Token::Str("114941315417899012"), ], ); serde_test::assert_de_tokens( - &Id::::new(114_941_315_417_899_012), + &Id::::new(114_941_315_417_899_012), &[ Token::NewtypeStruct { name: "Id" }, Token::Str("114941315417899012"), From dcf6ba25907d3007074ef6371dc14305b3567502 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Thu, 28 Sep 2023 15:43:29 -0400 Subject: [PATCH 14/21] add get SKUs route --- twilight-http-ratelimiting/src/request.rs | 4 +- twilight-http/src/client/mod.rs | 43 +++++++++++++++- .../application/monetization/get_skus.rs | 49 +++++++++++++++++++ .../request/application/monetization/mod.rs | 2 + twilight-http/src/request/try_into_request.rs | 3 +- twilight-http/src/routing.rs | 18 +++++++ .../src/application/monetization/sku.rs | 38 +++++++------- 7 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 twilight-http/src/request/application/monetization/get_skus.rs diff --git a/twilight-http-ratelimiting/src/request.rs b/twilight-http-ratelimiting/src/request.rs index cc6a4447a1e..ed65e648555 100644 --- a/twilight-http-ratelimiting/src/request.rs +++ b/twilight-http-ratelimiting/src/request.rs @@ -162,8 +162,10 @@ pub enum Path { ChannelsIdTyping(u64), /// Operating on a channel's webhooks. ChannelsIdWebhooks(u64), - /// Operating on an applications's entitlements. + /// Operating on an application's entitlements. ApplicationIdEntitlements(u64), + /// Operating on an application's SKUs. + ApplicationIdSKUs(u64), /// Operating with the gateway information. Gateway, /// Operating with the gateway information tailored to the current user. diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index b3089ee95a6..d298b27f273 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -7,7 +7,7 @@ pub use self::{builder::ClientBuilder, interaction::InteractionClient}; use crate::request::{ application::monetization::{ create_test_entitlement::{CreateTestEntitlement, CreateTestEntitlementOwner}, - DeleteTestEntitlement, GetEntitlements, + DeleteTestEntitlement, GetEntitlements, GetSKUs, }, guild::GetGuildOnboarding, GetCurrentAuthorizationInformation, @@ -2615,6 +2615,26 @@ impl Client { /// Deletes a currently-active test entitlement. Discord will act as though that user or /// guild no longer has entitlement to your premium offering. + /// + /// # Examples + /// + /// ```no_run + /// use twilight_http::Client; + /// use twilight_model::id::Id; + /// + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = Client::new("my token".to_owned()); + /// + /// let application_id = Id::new(1); + /// let entitlement_id = Id::new(2); + /// + /// client.delete_test_entitlement( + /// application_id, + /// entitlement_id, + /// ).await?; + /// + /// # Ok(()) } pub const fn delete_test_entitlement( &self, application_id: Id, @@ -2623,6 +2643,27 @@ impl Client { DeleteTestEntitlement::new(self, application_id, entitlement_id) } + /// Returns all SKUs for a given application. + /// + /// # Examples + /// + /// ```no_run + /// use twilight_http::Client; + /// use twilight_model::id::Id; + /// + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = Client::new("my token".to_owned()); + /// + /// let application_id = Id::new(1); + /// + /// let skus = client.get_skus(application_id).await?; + /// + /// # Ok(()) } + pub const fn get_skus(&self, application_id: Id) -> GetSKUs<'_> { + GetSKUs::new(self, application_id) + } + /// Execute a request, returning a future resolving to a [`Response`]. /// /// # Errors diff --git a/twilight-http/src/request/application/monetization/get_skus.rs b/twilight-http/src/request/application/monetization/get_skus.rs new file mode 100644 index 00000000000..16993744bde --- /dev/null +++ b/twilight-http/src/request/application/monetization/get_skus.rs @@ -0,0 +1,49 @@ +use std::future::IntoFuture; + +use twilight_model::{ + application::monetization::SKU, + id::{marker::ApplicationMarker, Id}, +}; + +use crate::{ + request::{Request, TryIntoRequest}, + response::{marker::ListBody, ResponseFuture}, + routing::Route, + Client, Error, Response, +}; + +pub struct GetSKUs<'a> { + application_id: Id, + http: &'a Client, +} + +impl<'a> GetSKUs<'a> { + pub(crate) const fn new(http: &'a Client, application_id: Id) -> Self { + Self { + application_id, + http, + } + } +} + +impl IntoFuture for GetSKUs<'_> { + type Output = Result>, Error>; + type IntoFuture = ResponseFuture>; + + fn into_future(self) -> Self::IntoFuture { + let http = self.http; + + match self.try_into_request() { + Ok(request) => http.request(request), + Err(source) => ResponseFuture::error(source), + } + } +} + +impl TryIntoRequest for GetSKUs<'_> { + fn try_into_request(self) -> Result { + Ok(Request::from_route(&Route::GetSKUs { + application_id: self.application_id.get(), + })) + } +} diff --git a/twilight-http/src/request/application/monetization/mod.rs b/twilight-http/src/request/application/monetization/mod.rs index 11fdb8dd257..d68ddf51228 100644 --- a/twilight-http/src/request/application/monetization/mod.rs +++ b/twilight-http/src/request/application/monetization/mod.rs @@ -1,7 +1,9 @@ pub mod create_test_entitlement; pub mod delete_test_entitlement; pub mod get_entitlements; +pub mod get_skus; pub use self::create_test_entitlement::{CreateTestEntitlement, CreateTestEntitlementOwner}; pub use self::delete_test_entitlement::DeleteTestEntitlement; pub use self::get_entitlements::GetEntitlements; +pub use self::get_skus::GetSKUs; diff --git a/twilight-http/src/request/try_into_request.rs b/twilight-http/src/request/try_into_request.rs index dc18316e700..3226ac16e10 100644 --- a/twilight-http/src/request/try_into_request.rs +++ b/twilight-http/src/request/try_into_request.rs @@ -20,7 +20,7 @@ mod private { }, monetization::{ create_test_entitlement::CreateTestEntitlement, get_entitlements::GetEntitlements, - DeleteTestEntitlement, + DeleteTestEntitlement, GetSKUs, }, }, channel::{ @@ -223,6 +223,7 @@ mod private { impl Sealed for GetPublicArchivedThreads<'_> {} impl Sealed for GetReactions<'_> {} impl Sealed for GetResponse<'_> {} + impl Sealed for GetSKUs<'_> {} impl Sealed for GetStageInstance<'_> {} impl Sealed for GetSticker<'_> {} impl Sealed for GetTemplate<'_> {} diff --git a/twilight-http/src/routing.rs b/twilight-http/src/routing.rs index 6612a13e35e..4759c58e2a0 100644 --- a/twilight-http/src/routing.rs +++ b/twilight-http/src/routing.rs @@ -780,6 +780,10 @@ pub enum Route<'a> { /// The ID of the message. message_id: u64, }, + GetSKUs { + /// The ID of the application. + application_id: u64, + }, /// Route information to get a stage instance. GetStageInstance { /// ID of the stage channel. @@ -1239,6 +1243,7 @@ impl<'a> Route<'a> { | Self::GetPrivateArchivedThreads { .. } | Self::GetPublicArchivedThreads { .. } | Self::GetReactionUsers { .. } + | Self::GetSKUs { .. } | Self::GetStageInstance { .. } | Self::GetSticker { .. } | Self::GetTemplate { .. } @@ -1616,6 +1621,7 @@ impl<'a> Route<'a> { Self::GetPins { channel_id } | Self::PinMessage { channel_id, .. } => { Path::ChannelsIdPins(channel_id) } + Self::GetSKUs { application_id } => Path::ApplicationIdSKUs(application_id), Self::GetSticker { .. } => Path::Stickers, Self::GetUserConnections => Path::UsersIdConnections, Self::GetVoiceRegions => Path::VoiceRegions, @@ -3009,6 +3015,12 @@ impl Display for Route<'_> { f.write_str("/mfa") } + Route::GetSKUs { application_id } => { + f.write_str("applications/")?; + Display::fmt(application_id, f)?; + + f.write_str("/skus") + } } } } @@ -4813,4 +4825,10 @@ mod tests { let route = Route::GetGuildOnboarding { guild_id: GUILD_ID }; assert_eq!(route.to_string(), format!("guilds/{GUILD_ID}/onboarding")); } + + #[test] + fn get_skus() { + let route = Route::GetSKUs { application_id: 1 }; + assert_eq!(route.to_string(), format!("applications/1/skus")); + } } diff --git a/twilight-model/src/application/monetization/sku.rs b/twilight-model/src/application/monetization/sku.rs index 5439de89916..993c0a0684d 100644 --- a/twilight-model/src/application/monetization/sku.rs +++ b/twilight-model/src/application/monetization/sku.rs @@ -10,19 +10,19 @@ use super::{SKUFlags, SKUType}; /// SKUs (stock-keeping units) in Discord represent premium offerings that can be made available to your application's users or guilds. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] pub struct SKU { + /// ID of the parent application. + application_id: Id, + /// Flags for the SKU. + flags: SKUFlags, /// ID of SKU. id: Id, /// Type of SKU. #[serde(rename = "type")] kind: SKUType, - /// ID of the parent application. - application_id: Id, /// Customer-facing name of your premium offering. name: String, /// System-generated URL slug based on the SKU's name. slug: String, - /// Flags for the SKU. - flags: SKUFlags, } #[cfg(test)] @@ -38,34 +38,36 @@ mod tests { #[test] fn sku() { + let value = SKU { + application_id: Id::new(1), + flags: SKUFlags::GUILD_SUBSCRIPTION, + id: Id::new(2), + kind: SKUType::Subscription, + name: "a name".to_owned(), + slug: "a-slug".to_owned(), + }; + serde_test::assert_tokens( - &SKU { - id: Id::new(1), - kind: SKUType::Subscription, - application_id: Id::new(2), - name: "a name".to_owned(), - slug: "a-slug".to_owned(), - flags: SKUFlags::GUILD_SUBSCRIPTION, - }, + &value, &[ Token::Struct { name: "SKU", len: 6, }, - Token::Str("id"), + Token::Str("application_id"), Token::NewtypeStruct { name: "Id" }, Token::Str("1"), - Token::Str("type"), - Token::U8(1), - Token::Str("application_id"), + Token::Str("flags"), + Token::U64(1 << 7), + Token::Str("id"), Token::NewtypeStruct { name: "Id" }, Token::Str("2"), + Token::Str("type"), + Token::U8(1), Token::Str("name"), Token::Str("a name"), Token::Str("slug"), Token::Str("a-slug"), - Token::Str("flags"), - Token::U64(1 << 7), Token::StructEnd, ], ); From 82ed05b80d4c541df0222224803a02ea29bbfebd Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Sun, 8 Oct 2023 19:22:15 -0400 Subject: [PATCH 15/21] make requeste changes --- twilight-http-ratelimiting/src/request.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/twilight-http-ratelimiting/src/request.rs b/twilight-http-ratelimiting/src/request.rs index ed65e648555..be5afd2b444 100644 --- a/twilight-http-ratelimiting/src/request.rs +++ b/twilight-http-ratelimiting/src/request.rs @@ -345,6 +345,7 @@ impl FromStr for Path { | ["applications", id, "guilds", _, "commands", _, "permissions"] => { ApplicationGuildCommandId(parse_id(id)?) } + ["applications", id, "skus"] => ApplicationIdSKUs(parse_id(id)?), ["channels", id] => ChannelsId(parse_id(id)?), ["channels", id, "followers"] => ChannelsIdFollowers(parse_id(id)?), ["channels", id, "invites"] => ChannelsIdInvites(parse_id(id)?), From 28d5de2bb70c50da81ceded87eaef23eb2429316 Mon Sep 17 00:00:00 2001 From: suneettipirneni Date: Sat, 21 Oct 2023 13:41:14 -0400 Subject: [PATCH 16/21] add updated changes --- twilight-model/src/application/interaction/mod.rs | 5 ++++- .../src/application/monetization/entitlement.rs | 7 ++++++- twilight-model/src/application/monetization/sku_flags.rs | 8 ++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/twilight-model/src/application/interaction/mod.rs b/twilight-model/src/application/interaction/mod.rs index 84c26d03fcb..160d2d8a47d 100644 --- a/twilight-model/src/application/interaction/mod.rs +++ b/twilight-model/src/application/interaction/mod.rs @@ -553,6 +553,7 @@ mod tests { entitlements: Vec::from([Entitlement { application_id: Id::new(100), consumed: false, + deleted: false, ends_at: None, guild_id: None, id: Id::new(200), @@ -729,13 +730,15 @@ mod tests { Token::Seq { len: Some(1) }, Token::Struct { name: "Entitlement", - len: 9, + len: 10, }, Token::Str("application_id"), Token::NewtypeStruct { name: "Id" }, Token::Str("100"), Token::Str("consumed"), Token::Bool(false), + Token::Str("deleted"), + Token::Bool(false), Token::Str("ends_at"), Token::None, Token::Str("guild_id"), diff --git a/twilight-model/src/application/monetization/entitlement.rs b/twilight-model/src/application/monetization/entitlement.rs index f8101d66bf9..9bbca490e21 100644 --- a/twilight-model/src/application/monetization/entitlement.rs +++ b/twilight-model/src/application/monetization/entitlement.rs @@ -17,6 +17,8 @@ pub struct Entitlement { pub application_id: Id, /// Not applicable for App Subscriptions. Subscriptions are not consumed and will be `false` pub consumed: bool, + /// Entitlement was deleted. + pub deleted: bool, /// Date at which the entitlement is no longer valid. Not present when using test entitlements. pub ends_at: Option, /// ID of the guild that is granted access to the entitlement's sku. @@ -55,6 +57,7 @@ mod tests { let value = Entitlement { application_id: Id::new(1), consumed: false, + deleted: false, ends_at: ends_at.into(), guild_id: Some(Id::new(10)), id: Id::new(2), @@ -69,13 +72,15 @@ mod tests { &[ Token::Struct { name: "Entitlement", - len: 9, + len: 10, }, Token::Str("application_id"), Token::NewtypeStruct { name: "Id" }, Token::Str("1"), Token::Str("consumed"), Token::Bool(false), + Token::Str("deleted"), + Token::Bool(false), Token::Str("ends_at"), Token::Some, Token::Str(ends_at_str), diff --git a/twilight-model/src/application/monetization/sku_flags.rs b/twilight-model/src/application/monetization/sku_flags.rs index 54339a988b8..fbe950a9b68 100644 --- a/twilight-model/src/application/monetization/sku_flags.rs +++ b/twilight-model/src/application/monetization/sku_flags.rs @@ -6,6 +6,8 @@ use serde::{ bitflags! { pub struct SKUFlags: u64 { + /// SKU is available for purchase. + const AVAILABLE = 1 << 2; /// A subscription purchased by a user and applied to a single server. /// Everyone in that server gets your premium benefits. const GUILD_SUBSCRIPTION = 1 << 7; @@ -74,11 +76,17 @@ mod tests { UpperHex ); + const_assert_eq!(SKUFlags::AVAILABLE.bits(), 1 << 2); const_assert_eq!(SKUFlags::GUILD_SUBSCRIPTION.bits(), 1 << 7); const_assert_eq!(SKUFlags::USER_SUBSCRIPTION.bits(), 1 << 8); #[test] fn serde() { + serde_test::assert_tokens( + &SKUFlags::AVAILABLE, + &[Token::U64(SKUFlags::AVAILABLE.bits())], + ); + serde_test::assert_tokens( &SKUFlags::GUILD_SUBSCRIPTION, &[Token::U64(SKUFlags::GUILD_SUBSCRIPTION.bits())], From 765250c442144cc625ef4aaf2e417c8bcb258406 Mon Sep 17 00:00:00 2001 From: Valdemar Erk Date: Sat, 13 Apr 2024 14:57:38 +0200 Subject: [PATCH 17/21] fix up merge --- twilight-http/src/client/mod.rs | 13 +++---------- .../monetization/create_test_entitlement.rs | 4 ++-- .../monetization/delete_test_entitlement.rs | 4 ++-- .../application/monetization/get_entitlements.rs | 2 +- .../src/application/monetization/sku_flags.rs | 1 + twilight-model/src/gateway/event/dispatch.rs | 7 ------- twilight-model/src/gateway/event/kind.rs | 2 -- twilight-model/src/gateway/event/mod.rs | 1 - 8 files changed, 9 insertions(+), 25 deletions(-) diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index 4e3142df288..dcbecb273e9 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -4,16 +4,9 @@ mod interaction; pub use self::{builder::ClientBuilder, interaction::InteractionClient}; -use crate::request::{ - application::monetization::{ - create_test_entitlement::{CreateTestEntitlement, CreateTestEntitlementOwner}, - DeleteTestEntitlement, GetEntitlements, GetSKUs, - }, - guild::{ - update_guild_onboarding::{UpdateGuildOnboarding, UpdateGuildOnboardingFields}, - GetGuildOnboarding, - }, - GetCurrentAuthorizationInformation, UpdateCurrentUserApplication, +use crate::request::application::monetization::{ + CreateTestEntitlement, CreateTestEntitlementOwner, DeleteTestEntitlement, GetEntitlements, + GetSKUs, }; #[allow(deprecated)] use crate::{ diff --git a/twilight-http/src/request/application/monetization/create_test_entitlement.rs b/twilight-http/src/request/application/monetization/create_test_entitlement.rs index f8f0ccb75bb..71f96299317 100644 --- a/twilight-http/src/request/application/monetization/create_test_entitlement.rs +++ b/twilight-http/src/request/application/monetization/create_test_entitlement.rs @@ -10,7 +10,7 @@ use twilight_model::{ }; use crate::{ - request::{Request, RequestBuilder, TryIntoRequest}, + request::{Request, TryIntoRequest}, response::ResponseFuture, routing::Route, Client, Error, Response, @@ -98,7 +98,7 @@ impl TryIntoRequest for CreateTestEntitlement<'_> { application_id: self.application_id.get(), }) .json(&self.fields) - .map(RequestBuilder::build) + .build() } } diff --git a/twilight-http/src/request/application/monetization/delete_test_entitlement.rs b/twilight-http/src/request/application/monetization/delete_test_entitlement.rs index db72780b1b8..b72ad8ee8be 100644 --- a/twilight-http/src/request/application/monetization/delete_test_entitlement.rs +++ b/twilight-http/src/request/application/monetization/delete_test_entitlement.rs @@ -49,10 +49,10 @@ impl IntoFuture for DeleteTestEntitlement<'_> { impl TryIntoRequest for DeleteTestEntitlement<'_> { fn try_into_request(self) -> Result { - Ok(Request::builder(&Route::DeleteTestEntitlement { + Request::builder(&Route::DeleteTestEntitlement { application_id: self.application_id.get(), entitlement_id: self.entitlement_id.get(), }) - .build()) + .build() } } diff --git a/twilight-http/src/request/application/monetization/get_entitlements.rs b/twilight-http/src/request/application/monetization/get_entitlements.rs index df938579588..6f24a4f04e8 100644 --- a/twilight-http/src/request/application/monetization/get_entitlements.rs +++ b/twilight-http/src/request/application/monetization/get_entitlements.rs @@ -92,7 +92,7 @@ impl<'a> GetEntitlements<'a> { /// is less than 1 or greater than 100. /// /// [`GetEntitlementsError`]: twilight_validate::request::ValidationErrorType::GetEntitlements - pub const fn limit(mut self, limit: u8) -> Result { + pub fn limit(mut self, limit: u8) -> Result { if let Err(source) = validate_get_entitlements_limit(limit) { return Err(source); } diff --git a/twilight-model/src/application/monetization/sku_flags.rs b/twilight-model/src/application/monetization/sku_flags.rs index fbe950a9b68..b9337df5224 100644 --- a/twilight-model/src/application/monetization/sku_flags.rs +++ b/twilight-model/src/application/monetization/sku_flags.rs @@ -5,6 +5,7 @@ use serde::{ }; bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SKUFlags: u64 { /// SKU is available for purchase. const AVAILABLE = 1 << 2; diff --git a/twilight-model/src/gateway/event/dispatch.rs b/twilight-model/src/gateway/event/dispatch.rs index 0576aeec8a0..9404e1f0d19 100644 --- a/twilight-model/src/gateway/event/dispatch.rs +++ b/twilight-model/src/gateway/event/dispatch.rs @@ -28,7 +28,6 @@ pub enum DispatchEvent { EntitlementCreate(EntitlementCreate), EntitlementDelete(EntitlementDelete), EntitlementUpdate(EntitlementUpdate), - GiftCodeUpdate, GuildAuditLogEntryCreate(Box), GuildCreate(Box), GuildDelete(GuildDelete), @@ -100,7 +99,6 @@ impl DispatchEvent { Self::EntitlementCreate(_) => EventType::EntitlementCreate, Self::EntitlementDelete(_) => EventType::EntitlementDelete, Self::EntitlementUpdate(_) => EventType::EntitlementUpdate, - Self::GiftCodeUpdate => EventType::GiftCodeUpdate, Self::GuildAuditLogEntryCreate(_) => EventType::GuildAuditLogEntryCreate, Self::GuildCreate(_) => EventType::GuildCreate, Self::GuildDelete(_) => EventType::GuildDelete, @@ -277,11 +275,6 @@ impl<'de, 'a> DeserializeSeed<'de> for DispatchEventWithTypeDeserializer<'a> { "ENTITLEMENT_CREATE" => { DispatchEvent::EntitlementCreate(EntitlementCreate::deserialize(deserializer)?) } - "GIFT_CODE_UPDATE" => { - deserializer.deserialize_ignored_any(IgnoredAny)?; - - DispatchEvent::GiftCodeUpdate - } "GUILD_AUDIT_LOG_ENTRY_CREATE" => DispatchEvent::GuildAuditLogEntryCreate(Box::new( GuildAuditLogEntryCreate::deserialize(deserializer)?, )), diff --git a/twilight-model/src/gateway/event/kind.rs b/twilight-model/src/gateway/event/kind.rs index bcc236ed035..d43dd68db97 100644 --- a/twilight-model/src/gateway/event/kind.rs +++ b/twilight-model/src/gateway/event/kind.rs @@ -108,7 +108,6 @@ impl EventType { Self::EntitlementCreate => Some("ENTITLEMENT_CREATE"), Self::EntitlementDelete => Some("ENTITLEMENT_DELETE"), Self::EntitlementUpdate => Some("ENTITLEMENT_UPDATE"), - Self::GiftCodeUpdate => Some("GIFT_CODE_UPDATE"), Self::GuildAuditLogEntryCreate => Some("GUILD_AUDIT_LOG_ENTRY_CREATE"), Self::GuildCreate => Some("GUILD_CREATE"), Self::GuildDelete => Some("GUILD_DELETE"), @@ -188,7 +187,6 @@ impl<'a> TryFrom<&'a str> for EventType { "CHANNEL_UPDATE" => Ok(Self::ChannelUpdate), "APPLICATION_COMMAND_PERMISSIONS_UPDATE" => Ok(Self::CommandPermissionsUpdate), "ENTITLEMENT_CREATE" => Ok(Self::EntitlementCreate), - "GIFT_CODE_UPDATE" => Ok(Self::GiftCodeUpdate), "GUILD_CREATE" => Ok(Self::GuildCreate), "GUILD_DELETE" => Ok(Self::GuildDelete), "GUILD_EMOJIS_UPDATE" => Ok(Self::GuildEmojisUpdate), diff --git a/twilight-model/src/gateway/event/mod.rs b/twilight-model/src/gateway/event/mod.rs index 82e44af2903..c6eaa63449b 100644 --- a/twilight-model/src/gateway/event/mod.rs +++ b/twilight-model/src/gateway/event/mod.rs @@ -351,7 +351,6 @@ impl From for Event { DispatchEvent::EntitlementCreate(v) => Self::EntitlementCreate(v), DispatchEvent::EntitlementDelete(v) => Self::EntitlementDelete(v), DispatchEvent::EntitlementUpdate(v) => Self::EntitlementUpdate(v), - DispatchEvent::GiftCodeUpdate => Self::GiftCodeUpdate, DispatchEvent::GuildAuditLogEntryCreate(v) => Self::GuildAuditLogEntryCreate(v), DispatchEvent::GuildCreate(v) => Self::GuildCreate(v), DispatchEvent::GuildDelete(v) => Self::GuildDelete(v), From d0c64478f1cf2a5105899a55e000cd6357eebdfe Mon Sep 17 00:00:00 2001 From: Valdemar Erk Date: Sat, 13 Apr 2024 15:45:21 +0200 Subject: [PATCH 18/21] resolve comments --- twilight-http/src/client/mod.rs | 4 +-- .../monetization/create_test_entitlement.rs | 6 ++-- .../monetization/get_entitlements.rs | 10 +++--- .../application/monetization/get_skus.rs | 6 ++-- twilight-http/src/routing.rs | 4 +-- .../src/application/interaction/mod.rs | 2 +- .../application/monetization/entitlement.rs | 4 +-- .../src/application/monetization/mod.rs | 4 +-- .../src/application/monetization/sku.rs | 22 ++++++------ .../src/application/monetization/sku_flags.rs | 34 +++++++++---------- .../src/application/monetization/sku_type.rs | 28 +++++++-------- twilight-model/src/id/marker.rs | 2 +- twilight-model/src/id/mod.rs | 8 ++--- 13 files changed, 67 insertions(+), 67 deletions(-) diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index dcbecb273e9..dcd6e5c9278 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -112,7 +112,7 @@ use twilight_model::{ marker::{ ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker, EntitlementMarker, GuildMarker, IntegrationMarker, MessageMarker, RoleMarker, - SKUMarker, ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, + SkuMarker, ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, }, Id, }, @@ -2616,7 +2616,7 @@ impl Client { pub const fn create_test_entitlement( &self, application_id: Id, - sku_id: Id, + sku_id: Id, owner: CreateTestEntitlementOwner, ) -> CreateTestEntitlement<'_> { CreateTestEntitlement::new(self, application_id, sku_id, owner) diff --git a/twilight-http/src/request/application/monetization/create_test_entitlement.rs b/twilight-http/src/request/application/monetization/create_test_entitlement.rs index 71f96299317..e053a62fd13 100644 --- a/twilight-http/src/request/application/monetization/create_test_entitlement.rs +++ b/twilight-http/src/request/application/monetization/create_test_entitlement.rs @@ -4,7 +4,7 @@ use serde::ser::{Serialize, SerializeStruct, Serializer}; use twilight_model::{ application::monetization::Entitlement, id::{ - marker::{ApplicationMarker, GuildMarker, SKUMarker, UserMarker}, + marker::{ApplicationMarker, GuildMarker, SkuMarker, UserMarker}, Id, }, }; @@ -39,7 +39,7 @@ impl CreateTestEntitlementOwner { } struct CreateTestEntitlementFields { - sku_id: Id, + sku_id: Id, owner: CreateTestEntitlementOwner, } @@ -66,7 +66,7 @@ impl<'a> CreateTestEntitlement<'a> { pub(crate) const fn new( http: &'a Client, application_id: Id, - sku_id: Id, + sku_id: Id, owner: CreateTestEntitlementOwner, ) -> Self { Self { diff --git a/twilight-http/src/request/application/monetization/get_entitlements.rs b/twilight-http/src/request/application/monetization/get_entitlements.rs index 6f24a4f04e8..f37b8f2a4e7 100644 --- a/twilight-http/src/request/application/monetization/get_entitlements.rs +++ b/twilight-http/src/request/application/monetization/get_entitlements.rs @@ -3,7 +3,7 @@ use std::future::IntoFuture; use twilight_model::{ application::monetization::Entitlement, id::{ - marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SKUMarker, UserMarker}, + marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SkuMarker, UserMarker}, Id, }, }; @@ -25,7 +25,7 @@ struct GetEntitlementsFields<'a> { exclude_ended: Option, guild_id: Option>, limit: Option, - sku_ids: &'a [Id], + sku_ids: &'a [Id], user_id: Option>, } @@ -33,15 +33,14 @@ struct GetEntitlementsFields<'a> { #[must_use = "requests must be configured and executed"] pub struct GetEntitlements<'a> { application_id: Id, - http: &'a Client, fields: GetEntitlementsFields<'a>, + http: &'a Client, } impl<'a> GetEntitlements<'a> { pub(crate) const fn new(http: &'a Client, application_id: Id) -> Self { Self { application_id, - http, fields: GetEntitlementsFields { after: None, before: None, @@ -51,6 +50,7 @@ impl<'a> GetEntitlements<'a> { sku_ids: &[], user_id: None, }, + http, } } @@ -103,7 +103,7 @@ impl<'a> GetEntitlements<'a> { } /// List of SKU IDs to check entitlements for. - pub const fn sku_ids(mut self, sku_ids: &'a [Id]) -> Self { + pub const fn sku_ids(mut self, sku_ids: &'a [Id]) -> Self { self.fields.sku_ids = sku_ids; self diff --git a/twilight-http/src/request/application/monetization/get_skus.rs b/twilight-http/src/request/application/monetization/get_skus.rs index 16993744bde..46555b01335 100644 --- a/twilight-http/src/request/application/monetization/get_skus.rs +++ b/twilight-http/src/request/application/monetization/get_skus.rs @@ -1,7 +1,7 @@ use std::future::IntoFuture; use twilight_model::{ - application::monetization::SKU, + application::monetization::Sku, id::{marker::ApplicationMarker, Id}, }; @@ -27,8 +27,8 @@ impl<'a> GetSKUs<'a> { } impl IntoFuture for GetSKUs<'_> { - type Output = Result>, Error>; - type IntoFuture = ResponseFuture>; + type Output = Result>, Error>; + type IntoFuture = ResponseFuture>; fn into_future(self) -> Self::IntoFuture { let http = self.http; diff --git a/twilight-http/src/routing.rs b/twilight-http/src/routing.rs index 7e3db9595d5..e605725dfb4 100644 --- a/twilight-http/src/routing.rs +++ b/twilight-http/src/routing.rs @@ -4,7 +4,7 @@ pub use twilight_http_ratelimiting::request::{Path, PathParseError, PathParseErr use crate::request::{channel::reaction::RequestReactionType, Method}; use std::fmt::{Display, Formatter, Result as FmtResult}; use twilight_model::id::{ - marker::{RoleMarker, SKUMarker}, + marker::{RoleMarker, SkuMarker}, Id, }; @@ -483,7 +483,7 @@ pub enum Route<'a> { /// Number of entitlements to return. Set to 100 if unspecified. limit: Option, /// List of SKU IDs to check entitlements for. - sku_ids: &'a [Id], + sku_ids: &'a [Id], /// User ID to look up entitlements for. user_id: Option, }, diff --git a/twilight-model/src/application/interaction/mod.rs b/twilight-model/src/application/interaction/mod.rs index a978108cd11..ff2f7d45cd7 100644 --- a/twilight-model/src/application/interaction/mod.rs +++ b/twilight-model/src/application/interaction/mod.rs @@ -551,7 +551,7 @@ mod tests { }), target_id: None, }))), - entitlements: Vec::from([Entitlement { + entitlements: vec![Entitlement { application_id: Id::new(100), consumed: false, deleted: false, diff --git a/twilight-model/src/application/monetization/entitlement.rs b/twilight-model/src/application/monetization/entitlement.rs index 9bbca490e21..6c2be6b706f 100644 --- a/twilight-model/src/application/monetization/entitlement.rs +++ b/twilight-model/src/application/monetization/entitlement.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ id::{ - marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SKUMarker, UserMarker}, + marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SkuMarker, UserMarker}, Id, }, util::Timestamp, @@ -29,7 +29,7 @@ pub struct Entitlement { #[serde(rename = "type")] pub kind: EntitlementType, /// ID of the SKU. - pub sku_id: Id, + pub sku_id: Id, /// Start date at which the entitlement is valid. Not present when using test entitlements. pub starts_at: Option, /// ID of the user that is granted access to the entitlement's sku. diff --git a/twilight-model/src/application/monetization/mod.rs b/twilight-model/src/application/monetization/mod.rs index 92140e53f0d..b9582652369 100644 --- a/twilight-model/src/application/monetization/mod.rs +++ b/twilight-model/src/application/monetization/mod.rs @@ -5,6 +5,6 @@ pub mod sku_flags; pub mod sku_type; pub use self::{ - entitlement::Entitlement, entitlement_type::EntitlementType, sku::SKU, sku_flags::SKUFlags, - sku_type::SKUType, + entitlement::Entitlement, entitlement_type::EntitlementType, sku::Sku, sku_flags::SkuFlags, + sku_type::SkuType, }; diff --git a/twilight-model/src/application/monetization/sku.rs b/twilight-model/src/application/monetization/sku.rs index 993c0a0684d..9a7717a4b85 100644 --- a/twilight-model/src/application/monetization/sku.rs +++ b/twilight-model/src/application/monetization/sku.rs @@ -1,24 +1,24 @@ use serde::{Deserialize, Serialize}; use crate::id::{ - marker::{ApplicationMarker, SKUMarker}, + marker::{ApplicationMarker, SkuMarker}, Id, }; -use super::{SKUFlags, SKUType}; +use super::{SkuFlags, SkuType}; /// SKUs (stock-keeping units) in Discord represent premium offerings that can be made available to your application's users or guilds. #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] -pub struct SKU { +pub struct Sku { /// ID of the parent application. application_id: Id, /// Flags for the SKU. - flags: SKUFlags, + flags: SkuFlags, /// ID of SKU. - id: Id, + id: Id, /// Type of SKU. #[serde(rename = "type")] - kind: SKUType, + kind: SkuType, /// Customer-facing name of your premium offering. name: String, /// System-generated URL slug based on the SKU's name. @@ -30,19 +30,19 @@ mod tests { use serde_test::Token; use crate::{ - application::monetization::{SKUFlags, SKUType}, + application::monetization::{SkuFlags, SkuType}, id::Id, }; - use super::SKU; + use super::Sku; #[test] fn sku() { - let value = SKU { + let value = Sku { application_id: Id::new(1), - flags: SKUFlags::GUILD_SUBSCRIPTION, + flags: SkuFlags::GUILD_SUBSCRIPTION, id: Id::new(2), - kind: SKUType::Subscription, + kind: SkuType::Subscription, name: "a name".to_owned(), slug: "a-slug".to_owned(), }; diff --git a/twilight-model/src/application/monetization/sku_flags.rs b/twilight-model/src/application/monetization/sku_flags.rs index b9337df5224..556d80fd371 100644 --- a/twilight-model/src/application/monetization/sku_flags.rs +++ b/twilight-model/src/application/monetization/sku_flags.rs @@ -6,7 +6,7 @@ use serde::{ bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - pub struct SKUFlags: u64 { + pub struct SkuFlags: u64 { /// SKU is available for purchase. const AVAILABLE = 1 << 2; /// A subscription purchased by a user and applied to a single server. @@ -18,13 +18,13 @@ bitflags! { } } -impl<'de> Deserialize<'de> for SKUFlags { +impl<'de> Deserialize<'de> for SkuFlags { fn deserialize>(deserializer: D) -> Result { Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) } } -impl Serialize for SKUFlags { +impl Serialize for SkuFlags { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -35,7 +35,7 @@ impl Serialize for SKUFlags { #[cfg(test)] mod tests { - use super::SKUFlags; + use super::SkuFlags; use serde::{Deserialize, Serialize}; use serde_test::Token; use static_assertions::{assert_impl_all, const_assert_eq}; @@ -48,7 +48,7 @@ mod tests { }; assert_impl_all!( - SKUFlags: Binary, + SkuFlags: Binary, BitAnd, BitAndAssign, BitOr, @@ -60,8 +60,8 @@ mod tests { Debug, Deserialize<'static>, Eq, - Extend, - FromIterator, + Extend, + FromIterator, Hash, LowerHex, Not, @@ -77,27 +77,27 @@ mod tests { UpperHex ); - const_assert_eq!(SKUFlags::AVAILABLE.bits(), 1 << 2); - const_assert_eq!(SKUFlags::GUILD_SUBSCRIPTION.bits(), 1 << 7); - const_assert_eq!(SKUFlags::USER_SUBSCRIPTION.bits(), 1 << 8); + const_assert_eq!(SkuFlags::AVAILABLE.bits(), 1 << 2); + const_assert_eq!(SkuFlags::GUILD_SUBSCRIPTION.bits(), 1 << 7); + const_assert_eq!(SkuFlags::USER_SUBSCRIPTION.bits(), 1 << 8); #[test] fn serde() { serde_test::assert_tokens( - &SKUFlags::AVAILABLE, - &[Token::U64(SKUFlags::AVAILABLE.bits())], + &SkuFlags::AVAILABLE, + &[Token::U64(SkuFlags::AVAILABLE.bits())], ); serde_test::assert_tokens( - &SKUFlags::GUILD_SUBSCRIPTION, - &[Token::U64(SKUFlags::GUILD_SUBSCRIPTION.bits())], + &SkuFlags::GUILD_SUBSCRIPTION, + &[Token::U64(SkuFlags::GUILD_SUBSCRIPTION.bits())], ); serde_test::assert_tokens( - &SKUFlags::USER_SUBSCRIPTION, - &[Token::U64(SKUFlags::USER_SUBSCRIPTION.bits())], + &SkuFlags::USER_SUBSCRIPTION, + &[Token::U64(SkuFlags::USER_SUBSCRIPTION.bits())], ); - serde_test::assert_de_tokens(&SKUFlags::empty(), &[Token::U64(1 << 63)]); + serde_test::assert_de_tokens(&SkuFlags::empty(), &[Token::U64(1 << 63)]); } } diff --git a/twilight-model/src/application/monetization/sku_type.rs b/twilight-model/src/application/monetization/sku_type.rs index 726174b08bb..5564e2bac74 100644 --- a/twilight-model/src/application/monetization/sku_type.rs +++ b/twilight-model/src/application/monetization/sku_type.rs @@ -2,40 +2,40 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[serde(from = "u8", into = "u8")] -pub enum SKUType { +pub enum SkuType { Subscription, SubscriptionGroup, Unknown(u8), } -impl From for SKUType { +impl From for SkuType { fn from(value: u8) -> Self { match value { - 1 => SKUType::Subscription, - 2 => SKUType::SubscriptionGroup, - other => SKUType::Unknown(other), + 5 => SkuType::Subscription, + 6 => SkuType::SubscriptionGroup, + other => SkuType::Unknown(other), } } } -impl From for u8 { - fn from(value: SKUType) -> Self { +impl From for u8 { + fn from(value: SkuType) -> Self { match value { - SKUType::Subscription => 1, - SKUType::SubscriptionGroup => 2, - SKUType::Unknown(other) => other, + SkuType::Subscription => 5, + SkuType::SubscriptionGroup => 6, + SkuType::Unknown(other) => other, } } } #[cfg(test)] mod tests { - use super::SKUType; + use super::SkuType; use serde_test::Token; #[test] fn sku_type() { - serde_test::assert_tokens(&SKUType::Subscription, &[Token::U8(1)]); - serde_test::assert_tokens(&SKUType::SubscriptionGroup, &[Token::U8(2)]); - serde_test::assert_tokens(&SKUType::Unknown(3), &[Token::U8(3)]); + serde_test::assert_tokens(&SkuType::Subscription, &[Token::U8(5)]); + serde_test::assert_tokens(&SkuType::SubscriptionGroup, &[Token::U8(6)]); + serde_test::assert_tokens(&SkuType::Unknown(3), &[Token::U8(3)]); } } diff --git a/twilight-model/src/id/marker.rs b/twilight-model/src/id/marker.rs index 662ffe110e3..13bfaafd5ac 100644 --- a/twilight-model/src/id/marker.rs +++ b/twilight-model/src/id/marker.rs @@ -101,7 +101,7 @@ pub struct EntitlementMarker; /// [`SKU`]: crate::application::monetization::sku::SKU #[derive(Debug)] #[non_exhaustive] -pub struct SKUMarker; +pub struct SkuMarker; /// Marker for generic IDs. /// diff --git a/twilight-model/src/id/mod.rs b/twilight-model/src/id/mod.rs index 43cce38f2d3..2d0ecb438c7 100644 --- a/twilight-model/src/id/mod.rs +++ b/twilight-model/src/id/mod.rs @@ -420,7 +420,7 @@ mod tests { ApplicationMarker, AttachmentMarker, AuditLogEntryMarker, ChannelMarker, CommandMarker, CommandVersionMarker, EmojiMarker, EntitlementMarker, GenericMarker, GuildMarker, IntegrationMarker, InteractionMarker, MessageMarker, RoleMarker, - RoleSubscriptionSkuMarker, SKUMarker, StageMarker, UserMarker, WebhookMarker, + RoleSubscriptionSkuMarker, SkuMarker, StageMarker, UserMarker, WebhookMarker, }, Id, }; @@ -444,7 +444,7 @@ mod tests { assert_impl_all!(CommandVersionMarker: Debug, Send, Sync); assert_impl_all!(EmojiMarker: Debug, Send, Sync); assert_impl_all!(EntitlementMarker: Debug, Send, Sync); - assert_impl_all!(SKUMarker: Debug, Send, Sync); + assert_impl_all!(SkuMarker: Debug, Send, Sync); assert_impl_all!(GenericMarker: Debug, Send, Sync); assert_impl_all!(GuildMarker: Debug, Send, Sync); assert_impl_all!(IntegrationMarker: Debug, Send, Sync); @@ -678,14 +678,14 @@ mod tests { ], ); serde_test::assert_tokens( - &Id::::new(114_941_315_417_899_012), + &Id::::new(114_941_315_417_899_012), &[ Token::NewtypeStruct { name: "Id" }, Token::Str("114941315417899012"), ], ); serde_test::assert_de_tokens( - &Id::::new(114_941_315_417_899_012), + &Id::::new(114_941_315_417_899_012), &[ Token::NewtypeStruct { name: "Id" }, Token::Str("114941315417899012"), From 8bb1a24fc62d7317c6d49b29312a0d408686fc63 Mon Sep 17 00:00:00 2001 From: Valdemar Erk Date: Sat, 13 Apr 2024 15:53:10 +0200 Subject: [PATCH 19/21] clippy and fmt because I forgot that --- twilight-http/src/client/mod.rs | 2 +- .../src/request/application/monetization/get_entitlements.rs | 4 +--- twilight-model/src/application/interaction/mod.rs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index dcd6e5c9278..9e8d71397f7 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -112,7 +112,7 @@ use twilight_model::{ marker::{ ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker, EntitlementMarker, GuildMarker, IntegrationMarker, MessageMarker, RoleMarker, - SkuMarker, ScheduledEventMarker, StickerMarker, UserMarker, WebhookMarker, + ScheduledEventMarker, SkuMarker, StickerMarker, UserMarker, WebhookMarker, }, Id, }, diff --git a/twilight-http/src/request/application/monetization/get_entitlements.rs b/twilight-http/src/request/application/monetization/get_entitlements.rs index f37b8f2a4e7..517467e490a 100644 --- a/twilight-http/src/request/application/monetization/get_entitlements.rs +++ b/twilight-http/src/request/application/monetization/get_entitlements.rs @@ -93,9 +93,7 @@ impl<'a> GetEntitlements<'a> { /// /// [`GetEntitlementsError`]: twilight_validate::request::ValidationErrorType::GetEntitlements pub fn limit(mut self, limit: u8) -> Result { - if let Err(source) = validate_get_entitlements_limit(limit) { - return Err(source); - } + validate_get_entitlements_limit(limit)?; self.fields.limit = Some(limit); diff --git a/twilight-model/src/application/interaction/mod.rs b/twilight-model/src/application/interaction/mod.rs index ff2f7d45cd7..2bd0397110d 100644 --- a/twilight-model/src/application/interaction/mod.rs +++ b/twilight-model/src/application/interaction/mod.rs @@ -562,7 +562,7 @@ mod tests { sku_id: Id::new(300), starts_at: None, user_id: None, - }]), + }], guild_id: Some(Id::new(400)), guild_locale: Some("de".to_owned()), id: Id::new(500), From 3cfca3aa9131fbb2cfbce768ed1880b184153edd Mon Sep 17 00:00:00 2001 From: Valdemar Erk Date: Sat, 13 Apr 2024 16:05:29 +0200 Subject: [PATCH 20/21] ord does not make sense for flags --- twilight-model/src/application/monetization/sku_flags.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/twilight-model/src/application/monetization/sku_flags.rs b/twilight-model/src/application/monetization/sku_flags.rs index 556d80fd371..f07830744fb 100644 --- a/twilight-model/src/application/monetization/sku_flags.rs +++ b/twilight-model/src/application/monetization/sku_flags.rs @@ -66,9 +66,7 @@ mod tests { LowerHex, Not, Octal, - Ord, PartialEq, - PartialOrd, Send, Serialize, Sub, From 54957d2d575c280432fed6bbdd64e41278c068c3 Mon Sep 17 00:00:00 2001 From: Valdemar Erk Date: Sat, 13 Apr 2024 16:05:39 +0200 Subject: [PATCH 21/21] fix a test --- twilight-model/src/application/monetization/sku.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/twilight-model/src/application/monetization/sku.rs b/twilight-model/src/application/monetization/sku.rs index 9a7717a4b85..517d7ccd04a 100644 --- a/twilight-model/src/application/monetization/sku.rs +++ b/twilight-model/src/application/monetization/sku.rs @@ -51,7 +51,7 @@ mod tests { &value, &[ Token::Struct { - name: "SKU", + name: "Sku", len: 6, }, Token::Str("application_id"), @@ -63,7 +63,7 @@ mod tests { Token::NewtypeStruct { name: "Id" }, Token::Str("2"), Token::Str("type"), - Token::U8(1), + Token::U8(5), Token::Str("name"), Token::Str("a name"), Token::Str("slug"),