serenity/builder/edit_scheduled_event.rs
1#[cfg(feature = "http")]
2use super::Builder;
3use super::CreateAttachment;
4#[cfg(feature = "http")]
5use crate::http::CacheHttp;
6#[cfg(feature = "http")]
7use crate::internal::prelude::*;
8use crate::model::prelude::*;
9
10/// [Discord docs](https://discord.com/developers/docs/resources/guild-scheduled-event#modify-guild-scheduled-event)
11#[derive(Clone, Debug, Default, Serialize)]
12#[must_use]
13pub struct EditScheduledEvent<'a> {
14 #[serde(skip_serializing_if = "Option::is_none")]
15 channel_id: Option<Option<ChannelId>>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 entity_metadata: Option<Option<ScheduledEventMetadata>>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 name: Option<String>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 privacy_level: Option<ScheduledEventPrivacyLevel>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 scheduled_start_time: Option<String>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 scheduled_end_time: Option<String>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 description: Option<String>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 entity_type: Option<ScheduledEventType>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 status: Option<ScheduledEventStatus>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 image: Option<String>,
34
35 #[serde(skip)]
36 audit_log_reason: Option<&'a str>,
37}
38
39impl<'a> EditScheduledEvent<'a> {
40 /// Equivalent to [`Self::default`].
41 pub fn new() -> Self {
42 Self::default()
43 }
44
45 /// Sets the channel id of the scheduled event. If the [`kind`] of the event is changed from
46 /// [`External`] to either [`StageInstance`] or [`Voice`], then this field is also required.
47 ///
48 /// [`kind`]: EditScheduledEvent::kind
49 /// [`Voice`]: ScheduledEventType::Voice
50 /// [`External`]: ScheduledEventType::External
51 pub fn channel_id(mut self, channel_id: impl Into<ChannelId>) -> Self {
52 self.channel_id = Some(Some(channel_id.into()));
53 self
54 }
55
56 /// Sets the name of the scheduled event.
57 pub fn name(mut self, name: impl Into<String>) -> Self {
58 self.name = Some(name.into());
59 self
60 }
61
62 /// The privacy level of the scheduled event
63 pub fn privacy_level(mut self, privacy_level: ScheduledEventPrivacyLevel) -> Self {
64 self.privacy_level = Some(privacy_level);
65 self
66 }
67
68 /// Sets the description of the scheduled event.
69 pub fn description(mut self, description: impl Into<String>) -> Self {
70 self.description = Some(description.into());
71 self
72 }
73
74 /// Sets the start time of the scheduled event.
75 #[inline]
76 pub fn start_time(mut self, timestamp: impl Into<Timestamp>) -> Self {
77 self.scheduled_start_time = Some(timestamp.into().to_string());
78 self
79 }
80
81 /// Sets the end time of the scheduled event.
82 ///
83 /// If the [`kind`] of the event is changed to [`External`], then this field is also required.
84 ///
85 /// [`kind`]: EditScheduledEvent::kind
86 /// [`External`]: ScheduledEventType::External
87 #[inline]
88 pub fn end_time(mut self, timestamp: impl Into<Timestamp>) -> Self {
89 self.scheduled_end_time = Some(timestamp.into().to_string());
90 self
91 }
92
93 /// Sets the entity type of the scheduled event.
94 ///
95 /// If changing to [`External`], then [`end_time`] and [`location`] must also be set.
96 /// Otherwise, if changing to either [`StageInstance`] or [`Voice`], then [`channel_id`] is
97 /// also required to be set.
98 ///
99 /// See the [Discord docs] for more details.
100 ///
101 /// [`channel_id`]: EditScheduledEvent::channel_id
102 /// [`end_time`]: EditScheduledEvent::end_time
103 /// [`location`]: EditScheduledEvent::location
104 ///
105 /// [`StageInstance`]: ScheduledEventType::StageInstance
106 /// [`Voice`]: ScheduledEventType::Voice
107 /// [`External`]: ScheduledEventType::External
108 /// [Discord docs]: https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-field-requirements-by-entity-type
109 pub fn kind(mut self, kind: ScheduledEventType) -> Self {
110 if let ScheduledEventType::External = kind {
111 self.channel_id = Some(None);
112 } else {
113 self.entity_metadata = Some(None);
114 }
115
116 self.entity_type = Some(kind);
117 self
118 }
119
120 /// Sets the status of the scheduled event.
121 ///
122 /// Only the following transitions are valid:
123 ///
124 /// [`Scheduled`] -> [`Active`]
125 ///
126 /// [`Active`] -> [`Completed`]
127 ///
128 /// [`Scheduled`] -> [`Canceled`]
129 ///
130 /// Additionally, if the event's status is [`Completed`] or [`Canceled`], then it can no longer
131 /// be updated.
132 ///
133 /// [`Scheduled`]: ScheduledEventStatus::Scheduled
134 /// [`Active`]: ScheduledEventStatus::Active
135 /// [`Completed`]: ScheduledEventStatus::Completed
136 /// [`Canceled`]: ScheduledEventStatus::Canceled
137 pub fn status(mut self, status: ScheduledEventStatus) -> Self {
138 self.status = Some(status);
139 self
140 }
141
142 /// Sets the location of the scheduled event.
143 ///
144 /// If the [`kind`] of the event is changed to [`External`], then this field is also required
145 /// to be set and non-empty.
146 ///
147 /// [`kind`]: EditScheduledEvent::kind
148 /// [`External`]: ScheduledEventType::External
149 pub fn location(mut self, location: impl Into<String>) -> Self {
150 self.entity_metadata = Some(Some(ScheduledEventMetadata {
151 location: Some(location.into()),
152 }));
153 self
154 }
155
156 /// Sets the cover image for the scheduled event.
157 pub fn image(mut self, image: &CreateAttachment) -> Self {
158 self.image = Some(image.to_base64());
159 self
160 }
161
162 /// Sets the request's audit log reason.
163 pub fn audit_log_reason(mut self, reason: &'a str) -> Self {
164 self.audit_log_reason = Some(reason);
165 self
166 }
167}
168
169#[cfg(feature = "http")]
170#[async_trait::async_trait]
171impl Builder for EditScheduledEvent<'_> {
172 type Context<'ctx> = (GuildId, ScheduledEventId);
173 type Built = ScheduledEvent;
174
175 /// Modifies a scheduled event in the guild with the data set, if any.
176 ///
177 /// **Note**: If the event was created by the current user, requires either [Create Events] or
178 /// the [Manage Events] permission. Otherwise, the [Manage Events] permission is required.
179 ///
180 /// # Errors
181 ///
182 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
183 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
184 ///
185 /// [Create Events]: Permissions::CREATE_EVENTS
186 /// [Manage Events]: Permissions::MANAGE_EVENTS
187 async fn execute(
188 self,
189 cache_http: impl CacheHttp,
190 ctx: Self::Context<'_>,
191 ) -> Result<Self::Built> {
192 cache_http.http().edit_scheduled_event(ctx.0, ctx.1, &self, self.audit_log_reason).await
193 }
194}