serenity/builder/
edit_role.rs1#[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#[derive(Clone, Debug, Default, Serialize)]
47#[must_use]
48pub struct EditRole<'a> {
49 #[serde(skip_serializing_if = "Option::is_none")]
50 name: Option<String>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 permissions: Option<u64>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 #[serde(rename = "color")]
55 colour: Option<Colour>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 #[serde(rename = "colors")]
58 colours: Option<CreateRoleColours>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 hoist: Option<bool>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 icon: Option<Option<String>>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 unicode_emoji: Option<Option<String>>,
65
66 #[serde(skip_serializing_if = "Option::is_none")]
67 mentionable: Option<bool>,
68
69 #[serde(skip)]
70 position: Option<u16>,
71 #[serde(skip)]
72 audit_log_reason: Option<&'a str>,
73}
74
75impl<'a> EditRole<'a> {
76 pub fn new() -> Self {
78 Self::default()
79 }
80
81 pub fn from_role(role: &Role) -> Self {
83 EditRole {
84 hoist: Some(role.hoist),
85 mentionable: Some(role.mentionable),
86 name: Some(role.name.clone()),
87 permissions: Some(role.permissions.bits()),
88 position: Some(role.position),
89 colour: Some(role.colour),
90 unicode_emoji: role.unicode_emoji.as_ref().map(|v| Some(v.clone())),
91 audit_log_reason: None,
92 colours: Some(role.colours.into()),
93 icon: None,
95 }
96 }
97
98 pub fn colour(mut self, colour: impl Into<Colour>) -> Self {
100 self.colour = Some(colour.into());
101 self
102 }
103
104 pub fn colours(mut self, colours: impl Into<CreateRoleColours>) -> Self {
106 self.colours = Some(colours.into());
107 self
108 }
109
110 pub fn hoist(mut self, hoist: bool) -> Self {
112 self.hoist = Some(hoist);
113 self
114 }
115
116 pub fn mentionable(mut self, mentionable: bool) -> Self {
119 self.mentionable = Some(mentionable);
120 self
121 }
122
123 pub fn name(mut self, name: impl Into<String>) -> Self {
125 self.name = Some(name.into());
126 self
127 }
128
129 pub fn permissions(mut self, permissions: Permissions) -> Self {
131 self.permissions = Some(permissions.bits());
132 self
133 }
134
135 pub fn position(mut self, position: u16) -> Self {
138 self.position = Some(position);
139 self
140 }
141
142 pub fn unicode_emoji(mut self, unicode_emoji: Option<String>) -> Self {
144 self.unicode_emoji = Some(unicode_emoji);
145 self.icon = Some(None);
146 self
147 }
148
149 pub fn icon(mut self, icon: Option<&CreateAttachment>) -> Self {
151 self.icon = Some(icon.map(CreateAttachment::to_base64));
152 self.unicode_emoji = Some(None);
153 self
154 }
155
156 pub fn audit_log_reason(mut self, reason: &'a str) -> Self {
158 self.audit_log_reason = Some(reason);
159 self
160 }
161}
162
163#[derive(Clone, Debug, Default, Serialize)]
170#[must_use]
171#[allow(clippy::struct_field_names)]
172pub struct CreateRoleColours {
173 primary_color: Colour,
174 #[serde(skip_serializing_if = "Option::is_none")]
175 secondary_color: Option<Colour>,
176 #[serde(skip_serializing_if = "Option::is_none")]
177 tertiary_color: Option<Colour>,
178}
179
180impl CreateRoleColours {
181 pub fn new(primary_colour: Colour) -> Self {
182 Self {
183 primary_color: primary_colour,
184 secondary_color: None,
185 tertiary_color: None,
186 }
187 }
188
189 pub fn secondary_colour(mut self, secondary_colour: Colour) -> Self {
191 self.secondary_color = Some(secondary_colour);
192 self
193 }
194
195 pub fn tertiary_colour(mut self, tertiary_colour: Colour) -> Self {
197 self.tertiary_color = Some(tertiary_colour);
198 self
199 }
200}
201
202impl From<RoleColours> for CreateRoleColours {
203 fn from(c: RoleColours) -> CreateRoleColours {
204 CreateRoleColours {
205 primary_color: c.primary_colour,
206 secondary_color: c.secondary_colour,
207 tertiary_color: c.tertiary_colour,
208 }
209 }
210}
211
212#[cfg(feature = "http")]
213#[async_trait::async_trait]
214impl Builder for EditRole<'_> {
215 type Context<'ctx> = (GuildId, Option<RoleId>);
216 type Built = Role;
217
218 async fn execute(
229 self,
230 cache_http: impl CacheHttp,
231 ctx: Self::Context<'_>,
232 ) -> Result<Self::Built> {
233 let (guild_id, role_id) = ctx;
234
235 #[cfg(feature = "cache")]
236 crate::utils::user_has_guild_perms(&cache_http, guild_id, Permissions::MANAGE_ROLES)?;
237
238 let http = cache_http.http();
239 let role = match role_id {
240 Some(role_id) => {
241 http.edit_role(guild_id, role_id, &self, self.audit_log_reason).await?
242 },
243 None => http.create_role(guild_id, &self, self.audit_log_reason).await?,
244 };
245
246 if let Some(position) = self.position {
247 http.edit_role_position(guild_id, role.id, position, self.audit_log_reason).await?;
248 }
249 Ok(role)
250 }
251}