serenity/builder/
edit_member.rs

1#[cfg(feature = "http")]
2use super::Builder;
3#[cfg(feature = "http")]
4use crate::http::CacheHttp;
5#[cfg(feature = "http")]
6use crate::internal::prelude::*;
7use crate::model::prelude::*;
8
9/// A builder which edits the properties of a [`Member`], to be used in conjunction with
10/// [`Member::edit`].
11///
12/// [Discord docs](https://discord.com/developers/docs/resources/guild#modify-guild-member)
13#[derive(Clone, Debug, Default, Serialize)]
14#[must_use]
15pub struct EditMember<'a> {
16    #[serde(skip_serializing_if = "Option::is_none")]
17    nick: Option<String>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    roles: Option<Vec<RoleId>>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    mute: Option<bool>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    deaf: Option<bool>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    channel_id: Option<Option<ChannelId>>,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    communication_disabled_until: Option<Option<String>>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    flags: Option<GuildMemberFlags>,
30
31    #[serde(skip)]
32    audit_log_reason: Option<&'a str>,
33}
34
35impl<'a> EditMember<'a> {
36    /// Equivalent to [`Self::default`].
37    pub fn new() -> Self {
38        Self::default()
39    }
40
41    /// Whether to deafen the member.
42    ///
43    /// **Note**: Requires the [Deafen Members] permission.
44    ///
45    /// [Deafen Members]: Permissions::DEAFEN_MEMBERS
46    pub fn deafen(mut self, deafen: bool) -> Self {
47        self.deaf = Some(deafen);
48        self
49    }
50
51    /// Whether to mute the member.
52    ///
53    /// **Note**: Requires the [Mute Members] permission.
54    ///
55    /// [Mute Members]: Permissions::MUTE_MEMBERS
56    pub fn mute(mut self, mute: bool) -> Self {
57        self.mute = Some(mute);
58        self
59    }
60
61    /// Changes the member's nickname. Pass an empty string to reset the nickname.
62    ///
63    /// **Note**: Requires the [Manage Nicknames] permission.
64    ///
65    /// [Manage Nicknames]: Permissions::MANAGE_NICKNAMES
66    pub fn nickname(mut self, nickname: impl Into<String>) -> Self {
67        self.nick = Some(nickname.into());
68        self
69    }
70
71    /// Set the list of roles that the member should have.
72    ///
73    /// **Note**: Requires the [Manage Roles] permission to modify.
74    ///
75    /// [Manage Roles]: Permissions::MANAGE_ROLES
76    pub fn roles(mut self, roles: impl IntoIterator<Item = impl Into<RoleId>>) -> Self {
77        self.roles = Some(roles.into_iter().map(Into::into).collect());
78        self
79    }
80
81    /// Move the member into a voice channel.
82    ///
83    /// **Note**: Requires the [Move Members] permission.
84    ///
85    /// [Move Members]: Permissions::MOVE_MEMBERS
86    #[inline]
87    pub fn voice_channel(mut self, channel_id: impl Into<ChannelId>) -> Self {
88        self.channel_id = Some(Some(channel_id.into()));
89        self
90    }
91
92    /// Disconnects the user from their voice channel, if any.
93    ///
94    /// **Note**: Requires the [Move Members] permission.
95    ///
96    /// [Move Members]: Permissions::MOVE_MEMBERS
97    pub fn disconnect_member(mut self) -> Self {
98        self.channel_id = Some(None);
99        self
100    }
101
102    /// Times the user out until `time`, an ISO8601-formatted datetime string.
103    ///
104    /// `time` is considered invalid if it is not a valid ISO8601 timestamp or if it is greater
105    /// than 28 days from the current time.
106    ///
107    /// **Note**: Requires the [Moderate Members] permission.
108    ///
109    /// [Moderate Members]: Permissions::MODERATE_MEMBERS
110    #[doc(alias = "timeout")]
111    pub fn disable_communication_until(mut self, time: String) -> Self {
112        self.communication_disabled_until = Some(Some(time));
113        self
114    }
115
116    /// Times the user out until `time`.
117    ///
118    /// `time` is considered invalid if it is greater than 28 days from the current time.
119    ///
120    /// **Note**: Requires the [Moderate Members] permission.
121    ///
122    /// [Moderate Members]: Permissions::MODERATE_MEMBERS
123    #[doc(alias = "timeout")]
124    pub fn disable_communication_until_datetime(self, time: Timestamp) -> Self {
125        self.disable_communication_until(time.to_string())
126    }
127
128    /// Allow a user to communicate, removing their timeout, if there is one.
129    ///
130    /// **Note**: Requires the [Moderate Members] permission.
131    ///
132    /// [Moderate Members]: Permissions::MODERATE_MEMBERS
133    #[doc(alias = "timeout")]
134    pub fn enable_communication(mut self) -> Self {
135        self.communication_disabled_until = Some(None);
136        self
137    }
138
139    pub fn flags(mut self, flags: GuildMemberFlags) -> Self {
140        self.flags = Some(flags);
141        self
142    }
143
144    /// Sets the request's audit log reason.
145    pub fn audit_log_reason(mut self, reason: &'a str) -> Self {
146        self.audit_log_reason = Some(reason);
147        self
148    }
149}
150
151#[cfg(feature = "http")]
152#[async_trait::async_trait]
153impl Builder for EditMember<'_> {
154    type Context<'ctx> = (GuildId, UserId);
155    type Built = Member;
156
157    /// Edits the properties of the guild member.
158    ///
159    /// For details on permissions requirements, refer to each specific method.
160    ///
161    /// # Errors
162    ///
163    /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
164    async fn execute(
165        self,
166        cache_http: impl CacheHttp,
167        ctx: Self::Context<'_>,
168    ) -> Result<Self::Built> {
169        cache_http.http().edit_member(ctx.0, ctx.1, &self, self.audit_log_reason).await
170    }
171}