titanium_model/
guild.rs

1use crate::member::{Emoji, Role, Sticker};
2use crate::snowflake::Snowflake;
3use crate::PartialVoiceState;
4use crate::TitanString;
5use crate::User;
6use serde::{Deserialize, Serialize};
7
8/// Discord Guild (Server) representation.
9#[derive(Debug, Clone, Deserialize, Serialize)]
10pub struct Guild<'a> {
11    /// Guild ID.
12    pub id: Snowflake,
13    /// Guild name (2-100 characters).
14    pub name: TitanString<'a>,
15    /// Icon hash.
16    #[serde(default)]
17    pub icon: Option<TitanString<'a>>,
18    /// Icon hash for animated icons.
19    #[serde(default)]
20    pub icon_hash: Option<TitanString<'a>>,
21    /// Splash hash.
22    #[serde(default)]
23    pub splash: Option<TitanString<'a>>,
24    /// Discovery splash hash.
25    #[serde(default)]
26    pub discovery_splash: Option<TitanString<'a>>,
27    /// ID of owner.
28    #[serde(default)]
29    pub owner_id: Option<Snowflake>,
30    /// Total permissions for the user in the guild.
31    #[serde(default)]
32    pub permissions: Option<crate::permissions::Permissions>,
33    /// Voice region ID (deprecated).
34    #[serde(default)]
35    pub region: Option<TitanString<'a>>,
36    /// ID of AFK channel.
37    #[serde(default)]
38    pub afk_channel_id: Option<Snowflake>,
39    /// AFK timeout in seconds.
40    #[serde(default)]
41    pub afk_timeout: Option<u32>,
42    /// Verification level required.
43    #[serde(default)]
44    pub verification_level: Option<u8>,
45    /// Default message notification level.
46    #[serde(default)]
47    pub default_message_notifications: Option<u8>,
48    /// Explicit content filter level.
49    #[serde(default)]
50    pub explicit_content_filter: Option<u8>,
51    /// Roles in the guild.
52    #[serde(default)]
53    pub roles: Vec<Role<'a>>,
54    /// Custom guild emojis.
55    #[serde(default)]
56    pub emojis: Vec<Emoji<'a>>,
57    /// Enabled guild features.
58    #[serde(default)]
59    pub features: Vec<TitanString<'a>>,
60    /// Required MFA level.
61    #[serde(default)]
62    pub mfa_level: Option<u8>,
63    /// Application ID of guild creator (if bot-created).
64    #[serde(default)]
65    pub application_id: Option<Snowflake>,
66    /// The ID of the channel for system messages.
67    #[serde(default)]
68    pub system_channel_id: Option<Snowflake>,
69    /// System channel flags.
70    #[serde(default)]
71    pub system_channel_flags: Option<u64>,
72    /// The ID of the channel for rules.
73    #[serde(default)]
74    pub rules_channel_id: Option<Snowflake>,
75    /// Max number of presences (null for large guilds).
76    #[serde(default)]
77    pub max_presences: Option<u32>,
78    /// Max number of members.
79    #[serde(default)]
80    pub max_members: Option<u32>,
81    /// Vanity URL code.
82    #[serde(default)]
83    pub vanity_url_code: Option<TitanString<'a>>,
84    /// Guild description.
85    #[serde(default)]
86    pub description: Option<TitanString<'a>>,
87    /// Banner hash.
88    #[serde(default)]
89    pub banner: Option<TitanString<'a>>,
90    /// Premium tier (boost level).
91    #[serde(default)]
92    pub premium_tier: Option<u8>,
93    /// Number of boosts.
94    #[serde(default)]
95    pub premium_subscription_count: Option<u32>,
96    /// Preferred locale.
97    #[serde(default)]
98    pub preferred_locale: Option<TitanString<'a>>,
99    /// The ID of the channel for public updates.
100    #[serde(default)]
101    pub public_updates_channel_id: Option<Snowflake>,
102    /// Max video channel users.
103    #[serde(default)]
104    pub max_video_channel_users: Option<u32>,
105    /// Max stage video channel users.
106    #[serde(default)]
107    pub max_stage_video_channel_users: Option<u32>,
108    /// Approximate member count.
109    #[serde(default)]
110    pub approximate_member_count: Option<u32>,
111    /// Approximate presence count.
112    #[serde(default)]
113    pub approximate_presence_count: Option<u32>,
114    /// Member count (only in `GUILD_CREATE`).
115    #[serde(default)]
116    pub member_count: Option<u64>,
117    /// Guild NSFW level.
118    #[serde(default)]
119    pub nsfw_level: Option<u8>,
120    /// Custom guild stickers.
121    #[serde(default)]
122    pub stickers: Vec<Sticker<'a>>,
123    /// Whether premium progress bar is enabled.
124    #[serde(default)]
125    pub premium_progress_bar_enabled: Option<bool>,
126    /// The ID of the channel for safety alerts.
127    #[serde(default)]
128    pub safety_alerts_channel_id: Option<Snowflake>,
129    /// Voice states (only in `GUILD_CREATE`).
130    #[serde(default)]
131    pub voice_states: Vec<PartialVoiceState<'a>>,
132}
133
134impl Guild<'_> {
135    /// Returns the URL of the guild's icon.
136    #[must_use]
137    pub fn icon_url(&self) -> Option<String> {
138        self.icon.as_ref().map(|hash| {
139            let ext = if hash.starts_with("a_") { "gif" } else { "png" };
140            format!(
141                "https://cdn.discordapp.com/icons/{}/{}.{}",
142                self.id, hash, ext
143            )
144        })
145    }
146
147    /// Returns the URL of the guild's splash.
148    #[must_use]
149    pub fn splash_url(&self) -> Option<String> {
150        self.splash.as_ref().map(|hash| {
151            format!(
152                "https://cdn.discordapp.com/splashes/{}/{}.png",
153                self.id, hash
154            )
155        })
156    }
157
158    /// Returns the URL of the guild's discovery splash.
159    #[must_use]
160    pub fn discovery_splash_url(&self) -> Option<String> {
161        self.discovery_splash.as_ref().map(|hash| {
162            format!(
163                "https://cdn.discordapp.com/discovery-splashes/{}/{}.png",
164                self.id, hash
165            )
166        })
167    }
168
169    /// Returns the URL of the guild's banner.
170    #[must_use]
171    pub fn banner_url(&self) -> Option<String> {
172        self.banner.as_ref().map(|hash| {
173            let ext = if hash.starts_with("a_") { "gif" } else { "png" };
174            format!(
175                "https://cdn.discordapp.com/banners/{}/{}.{}",
176                self.id, hash, ext
177            )
178        })
179    }
180}
181
182/// Unavailable Guild (during outages).
183#[derive(Debug, Clone, Deserialize, Serialize)]
184pub struct UnavailableGuild {
185    /// Guild ID.
186    pub id: Snowflake,
187    /// Whether unavailable.
188    #[serde(default)]
189    pub unavailable: bool,
190}
191
192// ============================================================================
193// Guild-related Events
194// ============================================================================
195
196/// Event data for `GUILD_MEMBER_UPDATE`.
197#[derive(Debug, Clone, Deserialize, Serialize)]
198pub struct GuildMemberUpdateEvent<'a> {
199    /// The ID of the guild.
200    pub guild_id: Snowflake,
201    /// User role IDs.
202    pub roles: Vec<Snowflake>,
203    /// The user.
204    pub user: User<'a>,
205    /// Nickname of the user.
206    #[serde(default)]
207    pub nick: Option<String>,
208    /// Member's guild avatar hash.
209    #[serde(default)]
210    pub avatar: Option<String>,
211    /// When the user joined the guild.
212    #[serde(default)]
213    pub joined_at: Option<String>,
214    /// When the user started boosting.
215    #[serde(default)]
216    pub premium_since: Option<String>,
217    /// Whether the user is deafened.
218    #[serde(default)]
219    pub deaf: Option<bool>,
220    /// Whether the user is muted.
221    #[serde(default)]
222    pub mute: Option<bool>,
223    /// Whether the user has not yet passed screening.
224    #[serde(default)]
225    pub pending: Option<bool>,
226    /// When the user's timeout will expire.
227    #[serde(default)]
228    pub communication_disabled_until: Option<String>,
229    /// Guild member flags.
230    #[serde(default)]
231    pub flags: Option<u64>,
232}
233
234/// Event data for `GUILD_MEMBER_REMOVE`.
235#[derive(Debug, Clone, Deserialize, Serialize)]
236pub struct GuildMemberRemoveEvent<'a> {
237    /// The ID of the guild.
238    pub guild_id: Snowflake,
239    /// The user who was removed.
240    pub user: User<'a>,
241}
242
243/// Event data for `GUILD_MEMBERS_CHUNK`.
244#[derive(Debug, Clone, Deserialize, Serialize)]
245pub struct GuildMembersChunkEvent<'a> {
246    /// The ID of the guild.
247    pub guild_id: Snowflake,
248    /// Set of guild members.
249    pub members: Vec<crate::member::GuildMember<'a>>,
250    /// Chunk index (starting from 0).
251    pub chunk_index: u32,
252    /// Total number of expected chunks.
253    pub chunk_count: u32,
254    /// If passing an invalid ID, it will be returned here.
255    #[serde(default)]
256    pub not_found: Vec<Snowflake>,
257    /// Presences (if requested).
258    #[serde(default)]
259    pub presences: Vec<crate::json::Value>,
260    /// Nonce used in the request.
261    #[serde(default)]
262    pub nonce: Option<String>,
263}
264
265/// Event data for `GUILD_BAN_ADD` / `GUILD_BAN_REMOVE`.
266#[derive(Debug, Clone, Deserialize, Serialize)]
267pub struct GuildBanEvent<'a> {
268    /// Guild ID.
269    pub guild_id: Snowflake,
270    /// The banned user.
271    pub user: User<'a>,
272}
273
274/// Event data for `GUILD_ROLE_CREATE` / `GUILD_ROLE_UPDATE`.
275#[derive(Debug, Clone, Deserialize, Serialize)]
276pub struct GuildRoleEvent<'a> {
277    /// Guild ID.
278    pub guild_id: Snowflake,
279    /// The role created or updated.
280    pub role: Role<'a>,
281}
282
283/// Event data for `GUILD_ROLE_DELETE`.
284#[derive(Debug, Clone, Deserialize, Serialize)]
285pub struct GuildRoleDeleteEvent {
286    /// Guild ID.
287    pub guild_id: Snowflake,
288    /// ID of the role.
289    pub role_id: Snowflake,
290}
291
292/// Event data for `GUILD_EMOJIS_UPDATE`.
293#[derive(Debug, Clone, Deserialize, Serialize)]
294pub struct GuildEmojisUpdateEvent<'a> {
295    /// Guild ID.
296    pub guild_id: Snowflake,
297    /// Array of emojis.
298    pub emojis: Vec<Emoji<'a>>,
299}
300
301/// Event data for `GUILD_STICKERS_UPDATE`.
302#[derive(Debug, Clone, Deserialize, Serialize)]
303pub struct GuildStickersUpdateEvent<'a> {
304    /// Guild ID.
305    pub guild_id: Snowflake,
306    /// Array of stickers.
307    pub stickers: Vec<Sticker<'a>>,
308}
309
310/// Event data for `GUILD_MEMBER_ADD`.
311#[derive(Debug, Clone, Deserialize, Serialize)]
312pub struct GuildMemberAddEvent<'a> {
313    /// The ID of the guild.
314    pub guild_id: Snowflake,
315    /// The user this member represents.
316    #[serde(default)]
317    pub user: Option<User<'a>>,
318    /// This user's guild nickname.
319    #[serde(default)]
320    pub nick: Option<String>,
321    /// The member's guild avatar hash.
322    #[serde(default)]
323    pub avatar: Option<String>,
324    /// Array of role object IDs.
325    #[serde(default)]
326    pub roles: Vec<Snowflake>,
327    /// When the user joined the guild.
328    pub joined_at: String,
329    /// Whether the user is deafened.
330    #[serde(default)]
331    pub deaf: bool,
332    /// Whether the user is muted.
333    #[serde(default)]
334    pub mute: bool,
335    /// Guild member flags.
336    #[serde(default)]
337    pub flags: u64,
338    /// Whether the user has not yet passed screening.
339    #[serde(default)]
340    pub pending: Option<bool>,
341}
342
343/// Ready event data.
344#[derive(Debug, Clone, Deserialize, Serialize)]
345pub struct ReadyEventData<'a> {
346    /// Gateway protocol version.
347    pub v: u8,
348    /// Current user.
349    pub user: User<'a>,
350    /// Guilds (unavailable at first).
351    pub guilds: Vec<UnavailableGuild>,
352    /// Session ID for resuming.
353    pub session_id: String,
354    /// Resume URL.
355    pub resume_gateway_url: String,
356    /// Shard info.
357    #[serde(default)]
358    pub shard: Option<[u16; 2]>,
359    /// Application information.
360    #[serde(default)]
361    pub application: Option<Application>,
362}
363
364/// Application information for Ready event.
365#[derive(Debug, Clone, Deserialize, Serialize)]
366pub struct Application {
367    /// Application ID.
368    pub id: Snowflake,
369    /// Application flags.
370    #[serde(default)]
371    pub flags: Option<u64>,
372}