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},
12 id::{
13 marker::{GuildMarker, RoleMarker},
14 Id,
15 },
16};
17use twilight_validate::request::{audit_reason as validate_audit_reason, ValidationError};
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 hoist: Option<bool>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 icon: Option<Nullable<&'a str>>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 mentionable: Option<bool>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 name: Option<Nullable<&'a str>>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 permissions: Option<Permissions>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 unicode_emoji: Option<Nullable<&'a str>>,
35}
36
37#[must_use = "requests must be configured and executed"]
39pub struct UpdateRole<'a> {
40 fields: UpdateRoleFields<'a>,
41 guild_id: Id<GuildMarker>,
42 http: &'a Client,
43 role_id: Id<RoleMarker>,
44 reason: Result<Option<&'a str>, ValidationError>,
45}
46
47impl<'a> UpdateRole<'a> {
48 pub(crate) const fn new(
49 http: &'a Client,
50 guild_id: Id<GuildMarker>,
51 role_id: Id<RoleMarker>,
52 ) -> Self {
53 Self {
54 fields: UpdateRoleFields {
55 color: None,
56 hoist: None,
57 icon: None,
58 mentionable: None,
59 name: None,
60 permissions: None,
61 unicode_emoji: None,
62 },
63 guild_id,
64 http,
65 role_id,
66 reason: Ok(None),
67 }
68 }
69
70 pub const fn color(mut self, color: Option<u32>) -> Self {
78 self.fields.color = Some(Nullable(color));
79
80 self
81 }
82
83 pub const fn hoist(mut self, hoist: bool) -> Self {
85 self.fields.hoist = Some(hoist);
86
87 self
88 }
89
90 pub const fn icon(mut self, icon: Option<&'a str>) -> Self {
128 self.fields.icon = Some(Nullable(icon));
129
130 self
131 }
132
133 pub const fn mentionable(mut self, mentionable: bool) -> Self {
135 self.fields.mentionable = Some(mentionable);
136
137 self
138 }
139
140 pub const fn name(mut self, name: Option<&'a str>) -> Self {
142 self.fields.name = Some(Nullable(name));
143
144 self
145 }
146
147 pub const fn permissions(mut self, permissions: Permissions) -> Self {
149 self.fields.permissions = Some(permissions);
150
151 self
152 }
153
154 pub const fn unicode_emoji(mut self, unicode_emoji: Option<&'a str>) -> Self {
187 self.fields.unicode_emoji = Some(Nullable(unicode_emoji));
188
189 self
190 }
191}
192
193impl<'a> AuditLogReason<'a> for UpdateRole<'a> {
194 fn reason(mut self, reason: &'a str) -> Self {
195 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
196
197 self
198 }
199}
200
201impl IntoFuture for UpdateRole<'_> {
202 type Output = Result<Response<Role>, Error>;
203
204 type IntoFuture = ResponseFuture<Role>;
205
206 fn into_future(self) -> Self::IntoFuture {
207 let http = self.http;
208
209 match self.try_into_request() {
210 Ok(request) => http.request(request),
211 Err(source) => ResponseFuture::error(source),
212 }
213 }
214}
215
216impl TryIntoRequest for UpdateRole<'_> {
217 fn try_into_request(self) -> Result<Request, Error> {
218 let mut request = Request::builder(&Route::UpdateRole {
219 guild_id: self.guild_id.get(),
220 role_id: self.role_id.get(),
221 });
222
223 request = request.json(&self.fields);
224
225 if let Some(reason) = self.reason.map_err(Error::validation)? {
226 request = request.headers(request::audit_header(reason)?);
227 }
228
229 request.build()
230 }
231}