twilight_http/request/guild/role/
update_role.rs1use crate::{
2 client::Client,
3 error::Error,
4 request::{self, AuditLogReason, Nullable, Request, TryIntoRequest},
5 response::{Response, ResponseFuture},
6 routing::Route,
7};
8use serde::Serialize;
9use std::future::IntoFuture;
10use twilight_model::{
11 guild::{Permissions, Role, RoleColors},
12 id::{
13 Id,
14 marker::{GuildMarker, RoleMarker},
15 },
16};
17use twilight_validate::request::{ValidationError, audit_reason as validate_audit_reason};
18
19#[derive(Serialize)]
20struct UpdateRoleFields<'a> {
21 #[serde(skip_serializing_if = "Option::is_none")]
22 color: Option<Nullable<u32>>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 colors: Option<Nullable<RoleColors>>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 hoist: Option<bool>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 icon: Option<Nullable<&'a str>>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 mentionable: Option<bool>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 name: Option<Nullable<&'a str>>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 permissions: Option<Permissions>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 unicode_emoji: Option<Nullable<&'a str>>,
37}
38
39#[must_use = "requests must be configured and executed"]
41pub struct UpdateRole<'a> {
42 fields: UpdateRoleFields<'a>,
43 guild_id: Id<GuildMarker>,
44 http: &'a Client,
45 role_id: Id<RoleMarker>,
46 reason: Result<Option<&'a str>, ValidationError>,
47}
48
49impl<'a> UpdateRole<'a> {
50 pub(crate) const fn new(
51 http: &'a Client,
52 guild_id: Id<GuildMarker>,
53 role_id: Id<RoleMarker>,
54 ) -> Self {
55 Self {
56 fields: UpdateRoleFields {
57 color: None,
58 colors: None,
59 hoist: None,
60 icon: None,
61 mentionable: None,
62 name: None,
63 permissions: None,
64 unicode_emoji: None,
65 },
66 guild_id,
67 http,
68 role_id,
69 reason: Ok(None),
70 }
71 }
72
73 pub const fn color(mut self, color: Option<u32>) -> Self {
81 self.fields.color = Some(Nullable(color));
82
83 self
84 }
85
86 pub const fn colors(mut self, colors: Option<RoleColors>) -> Self {
88 self.fields.colors = Some(Nullable(colors));
89
90 self
91 }
92
93 pub const fn hoist(mut self, hoist: bool) -> Self {
95 self.fields.hoist = Some(hoist);
96
97 self
98 }
99
100 pub const fn icon(mut self, icon: Option<&'a str>) -> Self {
138 self.fields.icon = Some(Nullable(icon));
139
140 self
141 }
142
143 pub const fn mentionable(mut self, mentionable: bool) -> Self {
145 self.fields.mentionable = Some(mentionable);
146
147 self
148 }
149
150 pub const fn name(mut self, name: Option<&'a str>) -> Self {
152 self.fields.name = Some(Nullable(name));
153
154 self
155 }
156
157 pub const fn permissions(mut self, permissions: Permissions) -> Self {
159 self.fields.permissions = Some(permissions);
160
161 self
162 }
163
164 pub const fn unicode_emoji(mut self, unicode_emoji: Option<&'a str>) -> Self {
197 self.fields.unicode_emoji = Some(Nullable(unicode_emoji));
198
199 self
200 }
201}
202
203impl<'a> AuditLogReason<'a> for UpdateRole<'a> {
204 fn reason(mut self, reason: &'a str) -> Self {
205 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
206
207 self
208 }
209}
210
211impl IntoFuture for UpdateRole<'_> {
212 type Output = Result<Response<Role>, Error>;
213
214 type IntoFuture = ResponseFuture<Role>;
215
216 fn into_future(self) -> Self::IntoFuture {
217 let http = self.http;
218
219 match self.try_into_request() {
220 Ok(request) => http.request(request),
221 Err(source) => ResponseFuture::error(source),
222 }
223 }
224}
225
226impl TryIntoRequest for UpdateRole<'_> {
227 fn try_into_request(self) -> Result<Request, Error> {
228 let mut request = Request::builder(&Route::UpdateRole {
229 guild_id: self.guild_id.get(),
230 role_id: self.role_id.get(),
231 });
232
233 request = request.json(&self.fields);
234
235 if let Some(reason) = self.reason.map_err(Error::validation)? {
236 request = request.headers(request::audit_header(reason)?);
237 }
238
239 request.build()
240 }
241}