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}