diff --git a/cache/in-memory/src/lib.rs b/cache/in-memory/src/lib.rs index 82f43c9b01b..ec00faf3ad1 100644 --- a/cache/in-memory/src/lib.rs +++ b/cache/in-memory/src/lib.rs @@ -873,6 +873,9 @@ mod tests { vanity_url_code: None, widget_channel_id: None, widget_enabled: None, + max_video_channel_users: None, + approximate_member_count: None, + approximate_presence_count: None, }; let cache = InMemoryCache::new(); diff --git a/http/src/client/mod.rs b/http/src/client/mod.rs index 0544e3099d1..bcc6cc593dc 100644 --- a/http/src/client/mod.rs +++ b/http/src/client/mod.rs @@ -424,12 +424,12 @@ impl Client { UpdateGuildChannelPositions::new(self, guild_id, channel_positions) } - pub fn guild_embed(&self, guild_id: GuildId) -> GetGuildEmbed<'_> { - GetGuildEmbed::new(self, guild_id) + pub fn guild_widget(&self, guild_id: GuildId) -> GetGuildWidget<'_> { + GetGuildWidget::new(self, guild_id) } - pub fn update_guild_embed(&self, guild_id: GuildId) -> UpdateGuildEmbed<'_> { - UpdateGuildEmbed::new(self, guild_id) + pub fn update_guild_widget(&self, guild_id: GuildId) -> UpdateGuildWidget<'_> { + UpdateGuildWidget::new(self, guild_id) } pub fn guild_integrations(&self, guild_id: GuildId) -> GetGuildIntegrations<'_> { diff --git a/http/src/request/guild/create_guild_prune.rs b/http/src/request/guild/create_guild_prune.rs index 555f2e4bb1c..abcc33dcfd2 100644 --- a/http/src/request/guild/create_guild_prune.rs +++ b/http/src/request/guild/create_guild_prune.rs @@ -3,7 +3,10 @@ use std::{ error::Error, fmt::{Display, Formatter, Result as FmtResult}, }; -use twilight_model::{guild::GuildPrune, id::GuildId}; +use twilight_model::{ + guild::GuildPrune, + id::{GuildId, RoleId}, +}; #[derive(Clone, Debug)] pub enum CreateGuildPruneError { @@ -25,6 +28,7 @@ impl Error for CreateGuildPruneError {} struct CreateGuildPruneFields { compute_prune_count: Option, days: Option, + include_roles: Vec, } pub struct CreateGuildPrune<'a> { @@ -46,6 +50,15 @@ impl<'a> CreateGuildPrune<'a> { } } + /// List of roles to include when pruning. + pub fn include_roles(mut self, roles: impl Iterator) -> Self { + let roles = roles.map(|e| e.0).collect::>(); + + self.fields.include_roles = roles; + + self + } + pub fn compute_prune_count(mut self, compute_prune_count: bool) -> Self { self.fields.compute_prune_count.replace(compute_prune_count); @@ -88,6 +101,7 @@ impl<'a> CreateGuildPrune<'a> { compute_prune_count: self.fields.compute_prune_count, days: self.fields.days, guild_id: self.guild_id.0, + include_roles: self.fields.include_roles.clone(), }, )) } else { @@ -95,6 +109,7 @@ impl<'a> CreateGuildPrune<'a> { compute_prune_count: self.fields.compute_prune_count, days: self.fields.days, guild_id: self.guild_id.0, + include_roles: self.fields.include_roles.clone(), }) }; diff --git a/http/src/request/guild/get_guild.rs b/http/src/request/guild/get_guild.rs index 5ae94ebdc30..8d40ac7a7df 100644 --- a/http/src/request/guild/get_guild.rs +++ b/http/src/request/guild/get_guild.rs @@ -1,7 +1,13 @@ use crate::request::prelude::*; use twilight_model::{guild::Guild, id::GuildId}; +#[derive(Default)] +struct GetGuildFields { + with_counts: bool, +} + pub struct GetGuild<'a> { + fields: GetGuildFields, fut: Option>>, guild_id: GuildId, http: &'a Client, @@ -10,16 +16,26 @@ pub struct GetGuild<'a> { impl<'a> GetGuild<'a> { pub(crate) fn new(http: &'a Client, guild_id: GuildId) -> Self { Self { + fields: GetGuildFields::default(), fut: None, guild_id, http, } } + /// Sets if you want to receive `approximate_member_count` and + /// `approximate_presence_count` in the guld structure. + pub fn with_counts(mut self, with: bool) -> Self { + self.fields.with_counts = with; + + self + } + fn start(&mut self) -> Result<()> { self.fut.replace(Box::pin(self.http.request(Request::from( Route::GetGuild { guild_id: self.guild_id.0, + with_counts: self.fields.with_counts, }, )))); diff --git a/http/src/request/guild/get_guild_prune_count.rs b/http/src/request/guild/get_guild_prune_count.rs index 76675cf0425..6e034ed5015 100644 --- a/http/src/request/guild/get_guild_prune_count.rs +++ b/http/src/request/guild/get_guild_prune_count.rs @@ -3,7 +3,10 @@ use std::{ error::Error, fmt::{Display, Formatter, Result as FmtResult}, }; -use twilight_model::{guild::GuildPrune, id::GuildId}; +use twilight_model::{ + guild::GuildPrune, + id::{GuildId, RoleId}, +}; #[derive(Clone, Debug)] pub enum GetGuildPruneCountError { @@ -24,6 +27,7 @@ impl Error for GetGuildPruneCountError {} #[derive(Default)] struct GetGuildPruneCountFields { days: Option, + include_roles: Vec, } pub struct GetGuildPruneCount<'a> { @@ -64,11 +68,21 @@ impl<'a> GetGuildPruneCount<'a> { Ok(self) } + /// List of roles to include when calculating prune count + pub fn include_roles(mut self, roles: impl Iterator) -> Self { + let roles = roles.map(|e| e.0).collect::>(); + + self.fields.include_roles = roles; + + self + } + fn start(&mut self) -> Result<()> { self.fut.replace(Box::pin(self.http.request(Request::from( Route::GetGuildPruneCount { days: self.fields.days, guild_id: self.guild_id.0, + include_roles: self.fields.include_roles.clone(), }, )))); diff --git a/http/src/request/guild/get_guild_embed.rs b/http/src/request/guild/get_guild_widget.rs similarity index 63% rename from http/src/request/guild/get_guild_embed.rs rename to http/src/request/guild/get_guild_widget.rs index 1747c26534d..f470ce9d6c2 100644 --- a/http/src/request/guild/get_guild_embed.rs +++ b/http/src/request/guild/get_guild_widget.rs @@ -1,13 +1,13 @@ use crate::request::prelude::*; -use twilight_model::{guild::GuildEmbed, id::GuildId}; +use twilight_model::{guild::GuildWidget, id::GuildId}; -pub struct GetGuildEmbed<'a> { - fut: Option>>, +pub struct GetGuildWidget<'a> { + fut: Option>>, guild_id: GuildId, http: &'a Client, } -impl<'a> GetGuildEmbed<'a> { +impl<'a> GetGuildWidget<'a> { pub(crate) fn new(http: &'a Client, guild_id: GuildId) -> Self { Self { fut: None, @@ -18,7 +18,7 @@ impl<'a> GetGuildEmbed<'a> { fn start(&mut self) -> Result<()> { self.fut.replace(Box::pin(self.http.request(Request::from( - Route::GetGuildEmbed { + Route::GetGuildWidget { guild_id: self.guild_id.0, }, )))); @@ -27,4 +27,4 @@ impl<'a> GetGuildEmbed<'a> { } } -poll_req!(GetGuildEmbed<'_>, Option); +poll_req!(GetGuildWidget<'_>, Option); diff --git a/http/src/request/guild/mod.rs b/http/src/request/guild/mod.rs index fec6337eebc..235543bfce3 100644 --- a/http/src/request/guild/mod.rs +++ b/http/src/request/guild/mod.rs @@ -12,25 +12,25 @@ pub mod role; mod delete_guild; mod get_guild; mod get_guild_channels; -mod get_guild_embed; mod get_guild_invites; mod get_guild_preview; mod get_guild_vanity_url; mod get_guild_voice_regions; mod get_guild_webhooks; +mod get_guild_widget; mod update_current_user_nick; mod update_guild; mod update_guild_channel_positions; -mod update_guild_embed; +mod update_guild_widget; pub use self::{ create_guild::CreateGuild, create_guild_channel::CreateGuildChannel, create_guild_prune::CreateGuildPrune, delete_guild::DeleteGuild, get_audit_log::GetAuditLog, - get_guild::GetGuild, get_guild_channels::GetGuildChannels, get_guild_embed::GetGuildEmbed, - get_guild_invites::GetGuildInvites, get_guild_preview::GetGuildPreview, - get_guild_prune_count::GetGuildPruneCount, get_guild_vanity_url::GetGuildVanityUrl, - get_guild_voice_regions::GetGuildVoiceRegions, get_guild_webhooks::GetGuildWebhooks, + get_guild::GetGuild, get_guild_channels::GetGuildChannels, get_guild_invites::GetGuildInvites, + get_guild_preview::GetGuildPreview, get_guild_prune_count::GetGuildPruneCount, + get_guild_vanity_url::GetGuildVanityUrl, get_guild_voice_regions::GetGuildVoiceRegions, + get_guild_webhooks::GetGuildWebhooks, get_guild_widget::GetGuildWidget, update_current_user_nick::UpdateCurrentUserNick, update_guild::UpdateGuild, update_guild_channel_positions::UpdateGuildChannelPositions, - update_guild_embed::UpdateGuildEmbed, + update_guild_widget::UpdateGuildWidget, }; diff --git a/http/src/request/guild/update_guild_embed.rs b/http/src/request/guild/update_guild_widget.rs similarity index 72% rename from http/src/request/guild/update_guild_embed.rs rename to http/src/request/guild/update_guild_widget.rs index 3d252827bb0..742a2229e08 100644 --- a/http/src/request/guild/update_guild_embed.rs +++ b/http/src/request/guild/update_guild_widget.rs @@ -1,26 +1,26 @@ use crate::request::prelude::*; use twilight_model::{ - guild::GuildEmbed, + guild::GuildWidget, id::{ChannelId, GuildId}, }; #[derive(Default, Serialize)] -struct UpdateGuildEmbedFields { +struct UpdateGuildWidgetFields { channel_id: Option, enabled: Option, } -pub struct UpdateGuildEmbed<'a> { - fields: UpdateGuildEmbedFields, - fut: Option>, +pub struct UpdateGuildWidget<'a> { + fields: UpdateGuildWidgetFields, + fut: Option>, guild_id: GuildId, http: &'a Client, } -impl<'a> UpdateGuildEmbed<'a> { +impl<'a> UpdateGuildWidget<'a> { pub(crate) fn new(http: &'a Client, guild_id: GuildId) -> Self { Self { - fields: UpdateGuildEmbedFields::default(), + fields: UpdateGuildWidgetFields::default(), fut: None, guild_id, http, @@ -42,7 +42,7 @@ impl<'a> UpdateGuildEmbed<'a> { fn start(&mut self) -> Result<()> { self.fut.replace(Box::pin(self.http.request(Request::from(( serde_json::to_vec(&self.fields)?, - Route::UpdateGuildEmbed { + Route::UpdateGuildWidget { guild_id: self.guild_id.0, }, ))))); @@ -51,4 +51,4 @@ impl<'a> UpdateGuildEmbed<'a> { } } -poll_req!(UpdateGuildEmbed<'_>, GuildEmbed); +poll_req!(UpdateGuildWidget<'_>, GuildWidget); diff --git a/http/src/routing.rs b/http/src/routing.rs index 1712aa952ff..3130088cd08 100644 --- a/http/src/routing.rs +++ b/http/src/routing.rs @@ -67,7 +67,7 @@ pub enum Path { GuildsIdAuditLogs(u64), GuildsIdBansUserId(u64), GuildsIdChannels(u64), - GuildsIdEmbed(u64), + GuildsIdWidget(u64), GuildsIdEmojis(u64), GuildsIdEmojisId(u64), GuildsIdIntegrations(u64), @@ -151,7 +151,7 @@ impl FromStr for Path { ["guilds", id, "bans"] => GuildsIdBans(id.parse()?), ["guilds", id, "bans", _] => GuildsIdBansUserId(id.parse()?), ["guilds", id, "channels"] => GuildsIdChannels(id.parse()?), - ["guilds", id, "embed"] => GuildsIdEmbed(id.parse()?), + ["guilds", id, "widget"] => GuildsIdWidget(id.parse()?), ["guilds", id, "emojis"] => GuildsIdEmojis(id.parse()?), ["guilds", id, "emojis", _] => GuildsIdEmojisId(id.parse()?), ["guilds", id, "integrations"] => GuildsIdIntegrations(id.parse()?), @@ -223,6 +223,7 @@ pub enum Route { compute_prune_count: Option, days: Option, guild_id: u64, + include_roles: Vec, }, CreateInvite { channel_id: u64, @@ -342,8 +343,9 @@ pub enum Route { GetGatewayBot, GetGuild { guild_id: u64, + with_counts: bool, }, - GetGuildEmbed { + GetGuildWidget { guild_id: u64, }, GetGuildIntegrations { @@ -364,6 +366,7 @@ pub enum Route { GetGuildPruneCount { days: Option, guild_id: u64, + include_roles: Vec, }, GetGuildRoles { guild_id: u64, @@ -460,7 +463,7 @@ pub enum Route { UpdateGuildChannels { guild_id: u64, }, - UpdateGuildEmbed { + UpdateGuildWidget { guild_id: u64, }, UpdateGuildIntegration { @@ -551,15 +554,28 @@ impl Route { compute_prune_count, days, guild_id, + include_roles, } => { let mut path = format!("guilds/{}/prune?", guild_id); if let Some(compute_prune_count) = compute_prune_count { - let _ = write!(path, "compute_prune_count={}", compute_prune_count,); + let _ = write!(path, "compute_prune_count={}&", compute_prune_count,); } if let Some(days) = days { - let _ = write!(path, "&days={}", days); + let _ = write!(path, "days={}&", days); + } + + if !include_roles.is_empty() { + let _ = write!( + path, + "include_roles={}", + include_roles + .iter() + .map(ToString::to_string) + .collect::>() + .join(",") + ); } (Method::POST, Path::GuildsIdPrune(guild_id), path.into()) @@ -793,15 +809,20 @@ impl Route { format!("guilds/{}/emojis", guild_id).into(), ), Self::GetGateway => (Method::GET, Path::Gateway, "gateway".into()), - Self::GetGuild { guild_id } => ( - Method::GET, - Path::GuildsId(guild_id), - format!("guilds/{}", guild_id).into(), - ), - Self::GetGuildEmbed { guild_id } => ( + Self::GetGuild { + guild_id, + with_counts, + } => { + let mut path = format!("guilds/{}", guild_id); + if with_counts { + let _ = write!(path, "?with_counts=true"); + } + (Method::GET, Path::GuildsId(guild_id), path.into()) + } + Self::GetGuildWidget { guild_id } => ( Method::GET, - Path::GuildsIdEmbed(guild_id), - format!("guilds/{}/embed", guild_id).into(), + Path::GuildsIdWidget(guild_id), + format!("guilds/{}/widget", guild_id).into(), ), Self::GetGuildIntegrations { guild_id } => ( Method::GET, @@ -840,11 +861,27 @@ impl Route { Path::GuildsIdPreview(guild_id), format!("guilds/{}/preview", guild_id).into(), ), - Self::GetGuildPruneCount { days, guild_id } => { + Self::GetGuildPruneCount { + days, + guild_id, + include_roles, + } => { let mut path = format!("guilds/{}/prune?", guild_id); if let Some(days) = days { - let _ = write!(path, "days={}", days); + let _ = write!(path, "days={}&", days); + } + + if !include_roles.is_empty() { + let _ = write!( + path, + "include_roles={}", + include_roles + .iter() + .map(ToString::to_string) + .collect::>() + .join(",") + ); } (Method::GET, Path::GuildsIdPrune(guild_id), path.into()) @@ -1065,10 +1102,10 @@ impl Route { Path::GuildsIdChannels(guild_id), format!("guilds/{}/channels", guild_id).into(), ), - Self::UpdateGuildEmbed { guild_id } => ( + Self::UpdateGuildWidget { guild_id } => ( Method::PATCH, - Path::GuildsIdEmbed(guild_id), - format!("guilds/{}/embed", guild_id).into(), + Path::GuildsIdWidget(guild_id), + format!("guilds/{}/widget", guild_id).into(), ), Self::UpdateGuildIntegration { guild_id, diff --git a/model/src/gateway/payload/invite_create.rs b/model/src/gateway/payload/invite_create.rs index 064345e0f49..4505605e494 100644 --- a/model/src/gateway/payload/invite_create.rs +++ b/model/src/gateway/payload/invite_create.rs @@ -1,4 +1,6 @@ use crate::id::{ChannelId, GuildId, UserId}; +use crate::invite::TargetUserType; +use crate::user::User; #[cfg_attr( feature = "serde-support", @@ -10,9 +12,11 @@ pub struct InviteCreate { pub code: String, pub created_at: String, pub guild_id: GuildId, - pub inviter: Option, + pub inviter: Option, pub max_age: u64, pub max_uses: u64, + pub target_user: Option, + pub target_user_type: Option, pub temporary: bool, pub uses: u8, // will always be zero } diff --git a/model/src/guild/mod.rs b/model/src/guild/mod.rs index 3929bb00746..c20fdeaa729 100644 --- a/model/src/guild/mod.rs +++ b/model/src/guild/mod.rs @@ -2,7 +2,6 @@ pub mod audit_log; mod ban; mod default_message_notification_level; -mod embed; mod emoji; mod explicit_content_filter; mod info; @@ -21,16 +20,17 @@ mod status; mod system_channel_flags; mod unavailable_guild; mod verification_level; +mod widget; pub use self::{ - ban::Ban, default_message_notification_level::DefaultMessageNotificationLevel, - embed::GuildEmbed, emoji::Emoji, explicit_content_filter::ExplicitContentFilter, - info::GuildInfo, integration::GuildIntegration, integration_account::IntegrationAccount, - member::Member, mfa_level::MfaLevel, partial_guild::PartialGuild, - partial_member::PartialMember, permissions::Permissions, premium_tier::PremiumTier, - preview::GuildPreview, prune::GuildPrune, role::Role, status::GuildStatus, - system_channel_flags::SystemChannelFlags, unavailable_guild::UnavailableGuild, - verification_level::VerificationLevel, + ban::Ban, default_message_notification_level::DefaultMessageNotificationLevel, emoji::Emoji, + explicit_content_filter::ExplicitContentFilter, info::GuildInfo, integration::GuildIntegration, + integration_account::IntegrationAccount, member::Member, mfa_level::MfaLevel, + partial_guild::PartialGuild, partial_member::PartialMember, permissions::Permissions, + premium_tier::PremiumTier, preview::GuildPreview, prune::GuildPrune, role::Role, + status::GuildStatus, system_channel_flags::SystemChannelFlags, + unavailable_guild::UnavailableGuild, verification_level::VerificationLevel, + widget::GuildWidget, }; use crate::{ @@ -100,4 +100,7 @@ pub struct Guild { pub vanity_url_code: Option, pub widget_channel_id: Option, pub widget_enabled: Option, + pub max_video_channel_users: Option, + pub approximate_member_count: Option, + pub approximate_presence_count: Option, } diff --git a/model/src/guild/embed.rs b/model/src/guild/widget.rs similarity index 89% rename from model/src/guild/embed.rs rename to model/src/guild/widget.rs index 72fca68a13c..5773e49520e 100644 --- a/model/src/guild/embed.rs +++ b/model/src/guild/widget.rs @@ -5,7 +5,7 @@ use crate::id::ChannelId; derive(serde::Deserialize, serde::Serialize) )] #[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub struct GuildEmbed { +pub struct GuildWidget { pub channel_id: ChannelId, pub enabled: bool, } diff --git a/model/src/user/connection.rs b/model/src/user/connection.rs index 05638213751..59a492975ae 100644 --- a/model/src/user/connection.rs +++ b/model/src/user/connection.rs @@ -10,12 +10,12 @@ use std::collections::HashMap; pub struct Connection { pub id: String, pub friend_sync: bool, - #[cfg_attr(feature = "serde-support", serde(with = "serde_mappable_seq"))] + #[cfg_attr(feature = "serde-support", serde(with = "serde_mappable_seq", default))] pub integrations: HashMap, #[cfg_attr(feature = "serde-support", serde(rename = "type"))] pub kind: String, pub name: String, - pub revoked: bool, + pub revoked: Option, pub show_activity: bool, pub verified: bool, pub visibility: ConnectionVisibility,