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<'a> Guild<'a> {
135    /// Returns the URL of the guild's icon.
136    pub fn icon_url(&self) -> Option<String> {
137        self.icon.as_ref().map(|hash| {
138            let ext = if hash.starts_with("a_") { "gif" } else { "png" };
139            format!(
140                "https://cdn.discordapp.com/icons/{}/{}.{}",
141                self.id, hash, ext
142            )
143        })
144    }
145
146    /// Returns the URL of the guild's splash.
147    pub fn splash_url(&self) -> Option<String> {
148        self.splash.as_ref().map(|hash| {
149            format!(
150                "https://cdn.discordapp.com/splashes/{}/{}.png",
151                self.id, hash
152            )
153        })
154    }
155
156    /// Returns the URL of the guild's discovery splash.
157    pub fn discovery_splash_url(&self) -> Option<String> {
158        self.discovery_splash.as_ref().map(|hash| {
159            format!(
160                "https://cdn.discordapp.com/discovery-splashes/{}/{}.png",
161                self.id, hash
162            )
163        })
164    }
165
166    /// Returns the URL of the guild's banner.
167    pub fn banner_url(&self) -> Option<String> {
168        self.banner.as_ref().map(|hash| {
169            let ext = if hash.starts_with("a_") { "gif" } else { "png" };
170            format!(
171                "https://cdn.discordapp.com/banners/{}/{}.{}",
172                self.id, hash, ext
173            )
174        })
175    }
176}
177
178/// Unavailable Guild (during outages).
179#[derive(Debug, Clone, Deserialize, Serialize)]
180pub struct UnavailableGuild {
181    /// Guild ID.
182    pub id: Snowflake,
183    /// Whether unavailable.
184    #[serde(default)]
185    pub unavailable: bool,
186}
187
188// ============================================================================
189// Guild-related Events
190// ============================================================================
191
192/// Event data for GUILD_MEMBER_UPDATE.
193#[derive(Debug, Clone, Deserialize, Serialize)]
194pub struct GuildMemberUpdateEvent<'a> {
195    /// The ID of the guild.
196    pub guild_id: Snowflake,
197    /// User role IDs.
198    pub roles: Vec<Snowflake>,
199    /// The user.
200    pub user: User<'a>,
201    /// Nickname of the user.
202    #[serde(default)]
203    pub nick: Option<String>,
204    /// Member's guild avatar hash.
205    #[serde(default)]
206    pub avatar: Option<String>,
207    /// When the user joined the guild.
208    #[serde(default)]
209    pub joined_at: Option<String>,
210    /// When the user started boosting.
211    #[serde(default)]
212    pub premium_since: Option<String>,
213    /// Whether the user is deafened.
214    #[serde(default)]
215    pub deaf: Option<bool>,
216    /// Whether the user is muted.
217    #[serde(default)]
218    pub mute: Option<bool>,
219    /// Whether the user has not yet passed screening.
220    #[serde(default)]
221    pub pending: Option<bool>,
222    /// When the user's timeout will expire.
223    #[serde(default)]
224    pub communication_disabled_until: Option<String>,
225    /// Guild member flags.
226    #[serde(default)]
227    pub flags: Option<u64>,
228}
229
230/// Event data for GUILD_MEMBER_REMOVE.
231#[derive(Debug, Clone, Deserialize, Serialize)]
232pub struct GuildMemberRemoveEvent<'a> {
233    /// The ID of the guild.
234    pub guild_id: Snowflake,
235    /// The user who was removed.
236    pub user: User<'a>,
237}
238
239/// Event data for GUILD_MEMBERS_CHUNK.
240#[derive(Debug, Clone, Deserialize, Serialize)]
241pub struct GuildMembersChunkEvent<'a> {
242    /// The ID of the guild.
243    pub guild_id: Snowflake,
244    /// Set of guild members.
245    pub members: Vec<crate::member::GuildMember<'a>>,
246    /// Chunk index (starting from 0).
247    pub chunk_index: u32,
248    /// Total number of expected chunks.
249    pub chunk_count: u32,
250    /// If passing an invalid ID, it will be returned here.
251    #[serde(default)]
252    pub not_found: Vec<Snowflake>,
253    /// Presences (if requested).
254    #[serde(default)]
255    pub presences: Vec<crate::json::Value>,
256    /// Nonce used in the request.
257    #[serde(default)]
258    pub nonce: Option<String>,
259}
260
261/// Event data for GUILD_BAN_ADD / GUILD_BAN_REMOVE.
262#[derive(Debug, Clone, Deserialize, Serialize)]
263pub struct GuildBanEvent<'a> {
264    /// Guild ID.
265    pub guild_id: Snowflake,
266    /// The banned user.
267    pub user: User<'a>,
268}
269
270/// Event data for GUILD_ROLE_CREATE / GUILD_ROLE_UPDATE.
271#[derive(Debug, Clone, Deserialize, Serialize)]
272pub struct GuildRoleEvent<'a> {
273    /// Guild ID.
274    pub guild_id: Snowflake,
275    /// The role created or updated.
276    pub role: Role<'a>,
277}
278
279/// Event data for GUILD_ROLE_DELETE.
280#[derive(Debug, Clone, Deserialize, Serialize)]
281pub struct GuildRoleDeleteEvent {
282    /// Guild ID.
283    pub guild_id: Snowflake,
284    /// ID of the role.
285    pub role_id: Snowflake,
286}
287
288/// Event data for GUILD_EMOJIS_UPDATE.
289#[derive(Debug, Clone, Deserialize, Serialize)]
290pub struct GuildEmojisUpdateEvent<'a> {
291    /// Guild ID.
292    pub guild_id: Snowflake,
293    /// Array of emojis.
294    pub emojis: Vec<Emoji<'a>>,
295}
296
297/// Event data for GUILD_STICKERS_UPDATE.
298#[derive(Debug, Clone, Deserialize, Serialize)]
299pub struct GuildStickersUpdateEvent<'a> {
300    /// Guild ID.
301    pub guild_id: Snowflake,
302    /// Array of stickers.
303    pub stickers: Vec<Sticker<'a>>,
304}
305
306/// Event data for GUILD_MEMBER_ADD.
307#[derive(Debug, Clone, Deserialize, Serialize)]
308pub struct GuildMemberAddEvent<'a> {
309    /// The ID of the guild.
310    pub guild_id: Snowflake,
311    /// The user this member represents.
312    #[serde(default)]
313    pub user: Option<User<'a>>,
314    /// This user's guild nickname.
315    #[serde(default)]
316    pub nick: Option<String>,
317    /// The member's guild avatar hash.
318    #[serde(default)]
319    pub avatar: Option<String>,
320    /// Array of role object IDs.
321    #[serde(default)]
322    pub roles: Vec<Snowflake>,
323    /// When the user joined the guild.
324    pub joined_at: String,
325    /// Whether the user is deafened.
326    #[serde(default)]
327    pub deaf: bool,
328    /// Whether the user is muted.
329    #[serde(default)]
330    pub mute: bool,
331    /// Guild member flags.
332    #[serde(default)]
333    pub flags: u64,
334    /// Whether the user has not yet passed screening.
335    #[serde(default)]
336    pub pending: Option<bool>,
337}
338
339/// Ready event data.
340#[derive(Debug, Clone, Deserialize, Serialize)]
341pub struct ReadyEventData<'a> {
342    /// Gateway protocol version.
343    pub v: u8,
344    /// Current user.
345    pub user: User<'a>,
346    /// Guilds (unavailable at first).
347    pub guilds: Vec<UnavailableGuild>,
348    /// Session ID for resuming.
349    pub session_id: String,
350    /// Resume URL.
351    pub resume_gateway_url: String,
352    /// Shard info.
353    #[serde(default)]
354    pub shard: Option<[u16; 2]>,
355    /// Application information.
356    #[serde(default)]
357    pub application: Option<Application>,
358}
359
360/// Application information for Ready event.
361#[derive(Debug, Clone, Deserialize, Serialize)]
362pub struct Application {
363    /// Application ID.
364    pub id: Snowflake,
365    /// Application flags.
366    #[serde(default)]
367    pub flags: Option<u64>,
368}