From e4494f4cd54d8a8701b004880f522cd41b272e9b Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Thu, 15 Dec 2022 15:12:11 +0400 Subject: [PATCH] Add support for application role connections metadata get/set operations --- twilight-http-ratelimiting/src/request.rs | 5 ++ twilight-http/src/client/mod.rs | 10 +++ twilight-http/src/client/role_connections.rs | 44 +++++++++++++ twilight-http/src/request/application/mod.rs | 1 + .../role_connections/get_metadata.rs | 60 +++++++++++++++++ .../application/role_connections/mod.rs | 4 ++ .../role_connections/set_metadata.rs | 65 +++++++++++++++++++ twilight-http/src/request/try_into_request.rs | 3 + twilight-http/src/routing.rs | 24 +++++++ twilight-model/src/application/mod.rs | 1 + .../src/application/role_connection/mod.rs | 54 +++++++++++++++ 11 files changed, 271 insertions(+) create mode 100644 twilight-http/src/client/role_connections.rs create mode 100644 twilight-http/src/request/application/role_connections/get_metadata.rs create mode 100644 twilight-http/src/request/application/role_connections/mod.rs create mode 100644 twilight-http/src/request/application/role_connections/set_metadata.rs create mode 100644 twilight-model/src/application/role_connection/mod.rs diff --git a/twilight-http-ratelimiting/src/request.rs b/twilight-http-ratelimiting/src/request.rs index da61f6bfce3..2ae0df543bd 100644 --- a/twilight-http-ratelimiting/src/request.rs +++ b/twilight-http-ratelimiting/src/request.rs @@ -123,6 +123,8 @@ pub enum Path { ApplicationGuildCommand(u64), /// Operating on a specific command in a guild. ApplicationGuildCommandId(u64), + /// Operating on application role connections metadata. + ApplicationRoleConnectionsMetadata(u64), /// Operating on a channel. ChannelsId(u64), /// Operating on a channel's followers. @@ -334,6 +336,9 @@ impl FromStr for Path { | ["applications", id, "guilds", _, "commands", _, "permissions"] => { ApplicationGuildCommandId(parse_id(id)?) } + ["applications", id, "role-connections", "metadata"] => { + ApplicationRoleConnectionsMetadata(parse_id(id)?) + } ["channels", id] => ChannelsId(parse_id(id)?), ["channels", id, "followers"] => ChannelsIdFollowers(parse_id(id)?), ["channels", id, "invites"] => ChannelsIdInvites(parse_id(id)?), diff --git a/twilight-http/src/client/mod.rs b/twilight-http/src/client/mod.rs index 4e22c249560..3f1bb9f297a 100644 --- a/twilight-http/src/client/mod.rs +++ b/twilight-http/src/client/mod.rs @@ -1,7 +1,9 @@ mod builder; mod connector; mod interaction; +mod role_connections; +use self::role_connections::RoleConnectionsClient; pub use self::{builder::ClientBuilder, interaction::InteractionClient}; #[allow(deprecated)] @@ -276,6 +278,14 @@ impl Client { InteractionClient::new(self, application_id) } + /// Create an interface for using application role connections. + pub const fn role_connections( + &self, + application_id: Id, + ) -> RoleConnectionsClient<'_> { + RoleConnectionsClient::new(self, application_id) + } + /// Get an immutable reference to the default [`AllowedMentions`] for sent /// messages. pub const fn default_allowed_mentions(&self) -> Option<&AllowedMentions> { diff --git a/twilight-http/src/client/role_connections.rs b/twilight-http/src/client/role_connections.rs new file mode 100644 index 00000000000..445606b4530 --- /dev/null +++ b/twilight-http/src/client/role_connections.rs @@ -0,0 +1,44 @@ +use crate::{ + request::application::role_connections::{GetMetadata, SetMetadata}, + Client, +}; +use twilight_model::{ + application::role_connection::Metadata, + id::{marker::ApplicationMarker, Id}, +}; + +/// Client interface for application role connections. +#[derive(Debug)] +pub struct RoleConnectionsClient<'a> { + application_id: Id, + client: &'a Client, +} + +impl<'a> RoleConnectionsClient<'a> { + /// Create a new interface for using interactions. + pub(super) const fn new(client: &'a Client, application_id: Id) -> Self { + Self { + application_id, + client, + } + } + + /// Get application role connections metadata. + pub const fn metadata(&'a self) -> GetMetadata<'a> { + GetMetadata::new(self.client, self.application_id) + } + + /// Set the application role connections metadata. + pub const fn set_metadata(&'a self, records: &'a [Metadata]) -> SetMetadata<'a> { + SetMetadata::new(self.client, self.application_id, records) + } +} + +#[cfg(test)] +mod tests { + use super::RoleConnectionsClient; + use static_assertions::assert_impl_all; + use std::fmt::Debug; + + assert_impl_all!(RoleConnectionsClient<'_>: Debug, Send, Sync); +} diff --git a/twilight-http/src/request/application/mod.rs b/twilight-http/src/request/application/mod.rs index c87d55ae72c..8f925b35f83 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 role_connections; diff --git a/twilight-http/src/request/application/role_connections/get_metadata.rs b/twilight-http/src/request/application/role_connections/get_metadata.rs new file mode 100644 index 00000000000..5d9d486f1f7 --- /dev/null +++ b/twilight-http/src/request/application/role_connections/get_metadata.rs @@ -0,0 +1,60 @@ +use crate::{ + client::Client, + error::Error, + request::{Request, TryIntoRequest}, + response::{marker::ListBody, Response, ResponseFuture}, + routing::Route, +}; +use std::future::IntoFuture; +use twilight_model::{ + application::role_connection::Metadata, + id::{marker::ApplicationMarker, Id}, +}; + +/// Get Application Role Connection Metadata Records. +#[must_use = "requests must be configured and executed"] +pub struct GetMetadata<'a> { + application_id: Id, + http: &'a Client, +} + +impl<'a> GetMetadata<'a> { + pub(crate) const fn new(http: &'a Client, application_id: Id) -> Self { + Self { + application_id, + http, + } + } + + /// Execute the request, returning a future resolving to a [`Response`]. + #[deprecated(since = "0.14.0", note = "use `.await` or `into_future` instead")] + pub fn exec(self) -> ResponseFuture> { + self.into_future() + } +} + +impl IntoFuture for GetMetadata<'_> { + 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 GetMetadata<'_> { + fn try_into_request(self) -> Result { + Ok( + Request::builder(&Route::GetApplicationRoleConnectionMetadataRecords { + application_id: self.application_id.get(), + }) + .build(), + ) + } +} diff --git a/twilight-http/src/request/application/role_connections/mod.rs b/twilight-http/src/request/application/role_connections/mod.rs new file mode 100644 index 00000000000..36339d23240 --- /dev/null +++ b/twilight-http/src/request/application/role_connections/mod.rs @@ -0,0 +1,4 @@ +mod get_metadata; +mod set_metadata; + +pub use self::{get_metadata::GetMetadata, set_metadata::SetMetadata}; diff --git a/twilight-http/src/request/application/role_connections/set_metadata.rs b/twilight-http/src/request/application/role_connections/set_metadata.rs new file mode 100644 index 00000000000..b51a33d7f30 --- /dev/null +++ b/twilight-http/src/request/application/role_connections/set_metadata.rs @@ -0,0 +1,65 @@ +use crate::{ + client::Client, + error::Error, + request::{Request, RequestBuilder, TryIntoRequest}, + response::{marker::ListBody, Response, ResponseFuture}, + routing::Route, +}; +use std::future::IntoFuture; +use twilight_model::{ + application::role_connection::Metadata, + id::{marker::ApplicationMarker, Id}, +}; + +/// Set a user's linked roles metadata for the given application. +#[must_use = "requests must be configured and executed"] +pub struct SetMetadata<'a> { + application_id: Id, + http: &'a Client, + records: &'a [Metadata], +} + +impl<'a> SetMetadata<'a> { + pub(crate) const fn new( + http: &'a Client, + application_id: Id, + records: &'a [Metadata], + ) -> Self { + Self { + application_id, + http, + records, + } + } + + /// Execute the request, returning a future resolving to a [`Response`]. + #[deprecated(since = "0.14.0", note = "use `.await` or `into_future` instead")] + pub fn exec(self) -> ResponseFuture> { + self.into_future() + } +} + +impl IntoFuture for SetMetadata<'_> { + 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 SetMetadata<'_> { + fn try_into_request(self) -> Result { + Request::builder(&Route::SetApplicationRoleConnectionMetadataRecords { + application_id: self.application_id.get(), + }) + .json(&self.records) + .map(RequestBuilder::build) + } +} diff --git a/twilight-http/src/request/try_into_request.rs b/twilight-http/src/request/try_into_request.rs index a8c6ec2813f..84cd517ad91 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, }, + role_connections::{GetMetadata, SetMetadata}, }, channel::{ invite::{CreateInvite, DeleteInvite, GetChannelInvites, GetInvite}, @@ -206,6 +207,7 @@ mod private { impl Sealed for GetJoinedPrivateArchivedThreads<'_> {} impl Sealed for GetMember<'_> {} impl Sealed for GetMessage<'_> {} + impl Sealed for GetMetadata<'_> {} impl Sealed for GetNitroStickerPacks<'_> {} impl Sealed for GetPins<'_> {} impl Sealed for GetPrivateArchivedThreads<'_> {} @@ -232,6 +234,7 @@ mod private { impl Sealed for SearchGuildMembers<'_> {} impl Sealed for SetGlobalCommands<'_> {} impl Sealed for SetGuildCommands<'_> {} + impl Sealed for SetMetadata<'_> {} impl Sealed for SyncTemplate<'_> {} impl Sealed for UpdateAutoModerationRule<'_> {} impl Sealed for UpdateChannel<'_> {} diff --git a/twilight-http/src/routing.rs b/twilight-http/src/routing.rs index a873f3ce005..05a564fe9ab 100644 --- a/twilight-http/src/routing.rs +++ b/twilight-http/src/routing.rs @@ -359,6 +359,12 @@ pub enum Route<'a> { /// ID of the guild. guild_id: u64, }, + /// Returns a list of application role connection metadata objects for the + /// given application. + GetApplicationRoleConnectionMetadataRecords { + /// The ID of the owner application. + application_id: u64, + }, /// Route information to get a paginated list of audit logs in a guild. GetAuditLogs { /// The type of action to get audit logs for. @@ -861,6 +867,12 @@ pub enum Route<'a> { /// Query to search by. query: &'a str, }, + /// Updates and returns a list of application role connection metadata + /// objects for the given application. + SetApplicationRoleConnectionMetadataRecords { + /// The ID of the owner application. + application_id: u64, + }, /// Route information to set global commands. SetGlobalCommands { /// The ID of the owner application. @@ -1130,6 +1142,7 @@ impl<'a> Route<'a> { | Self::RemoveThreadMember { .. } | Self::UnpinMessage { .. } => Method::Delete, Self::GetActiveThreads { .. } + | Self::GetApplicationRoleConnectionMetadataRecords { .. } | Self::GetAuditLogs { .. } | Self::GetAutoModerationRule { .. } | Self::GetBan { .. } @@ -1259,6 +1272,7 @@ impl<'a> Route<'a> { | Self::CreateReaction { .. } | Self::JoinThread { .. } | Self::PinMessage { .. } + | Self::SetApplicationRoleConnectionMetadataRecords { .. } | Self::SetGlobalCommands { .. } | Self::SetGuildCommands { .. } | Self::SyncTemplate { .. } @@ -1329,6 +1343,10 @@ impl<'a> Route<'a> { | Self::SetGlobalCommands { application_id } => { Path::ApplicationCommand(application_id) } + Self::GetApplicationRoleConnectionMetadataRecords { application_id } + | Self::SetApplicationRoleConnectionMetadataRecords { application_id } => { + Path::ApplicationRoleConnectionsMetadata(application_id) + } Self::CreateGuild => Path::Guilds, Self::CreateGuildFromTemplate { template_code, .. } | Self::GetTemplate { template_code, .. } => { @@ -1743,6 +1761,12 @@ impl Display for Route<'_> { Ok(()) } + Route::GetApplicationRoleConnectionMetadataRecords { application_id } + | Route::SetApplicationRoleConnectionMetadataRecords { application_id } => { + f.write_str("applications/")?; + Display::fmt(application_id, f)?; + f.write_str("/role-connections/metadata") + } Route::CreateGuild => f.write_str("guilds"), Route::CreateGuildCommand { application_id, diff --git a/twilight-model/src/application/mod.rs b/twilight-model/src/application/mod.rs index c87d55ae72c..d527b84b9fb 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 role_connection; diff --git a/twilight-model/src/application/role_connection/mod.rs b/twilight-model/src/application/role_connection/mod.rs new file mode 100644 index 00000000000..f6ba80bea6e --- /dev/null +++ b/twilight-model/src/application/role_connection/mod.rs @@ -0,0 +1,54 @@ +//! Application role connections models. + +use std::collections::HashMap; + +use serde::{Deserialize, Serialize}; +use serde_repr::{Deserialize_repr, Serialize_repr}; + +/// Application Role Connection Metadata Type. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize_repr, Serialize_repr)] +#[repr(u8)] +pub enum MetadataType { + /// the metadata value (integer) is less than or equal to the guild's + /// configured value (integer) + IntegerLessThanOrEqual = 1, + /// the metadata value (integer) is greater than or equal to the guild's + /// configured value (integer) + IntegerGreaterThanOrEqual = 2, + /// the metadata value (integer) is equal to the guild's configured value + /// (integer) + IntegerEqual = 3, + /// the metadata value (integer) is not equal to the guild's configured + /// value (integer) + IntegerNotEqual = 4, + /// the metadata value (ISO8601 string) is less than or equal to + /// the guild's configured value (integer; days before current date) + DatetimeLessThanOrEqual = 5, + /// the metadata value (ISO8601 string) is greater than or equal to + /// the guild's configured value (integer; days before current date) + DatetimeGreaterThanOrEqual = 6, + /// the metadata value (integer) is equal to the guild's configured value + /// (integer; 1) + BooleanEqual = 7, + /// the metadata value (integer) is not equal to the guild's configured + /// value (integer; 1) + BooleanNotEqual = 8, +} + +/// Application Role Connection Metadata Structure. +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] +pub struct Metadata { + /// type of metadata value + pub r#type: MetadataType, + /// dictionary key for the metadata field + /// (must be a-z, 0-9, or _ characters; max 50 characters) + pub key: String, + /// name of the metadata field (max 100 characters) + pub name: String, + /// translations of the name + pub name_localizations: HashMap, + /// description of the metadata field (max 200 characters) + pub description: String, + /// translations of the description + pub description_localizations: HashMap, +}