twilight_http/request/guild/role/
create_role.rs1use crate::{
2 client::Client,
3 error::Error,
4 request::{self, AuditLogReason, 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::{Id, marker::GuildMarker},
13};
14use twilight_validate::request::{ValidationError, audit_reason as validate_audit_reason};
15
16#[derive(Serialize)]
17struct CreateRoleFields<'a> {
18 #[serde(skip_serializing_if = "Option::is_none")]
19 color: Option<u32>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 colors: Option<RoleColors>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 hoist: Option<bool>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 icon: Option<&'a str>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 mentionable: Option<bool>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 name: Option<&'a str>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 permissions: Option<Permissions>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 unicode_emoji: Option<&'a str>,
34}
35
36#[must_use = "requests must be configured and executed"]
57pub struct CreateRole<'a> {
58 fields: CreateRoleFields<'a>,
59 guild_id: Id<GuildMarker>,
60 http: &'a Client,
61 reason: Result<Option<&'a str>, ValidationError>,
62}
63
64impl<'a> CreateRole<'a> {
65 pub(crate) const fn new(http: &'a Client, guild_id: Id<GuildMarker>) -> Self {
66 Self {
67 fields: CreateRoleFields {
68 color: None,
69 colors: None,
70 hoist: None,
71 icon: None,
72 mentionable: None,
73 name: None,
74 permissions: None,
75 unicode_emoji: None,
76 },
77 guild_id,
78 http,
79 reason: Ok(None),
80 }
81 }
82
83 pub const fn color(mut self, color: u32) -> Self {
91 self.fields.color = Some(color);
92
93 self
94 }
95
96 pub const fn colors(mut self, colors: RoleColors) -> Self {
98 self.fields.colors = Some(colors);
99
100 self
101 }
102
103 pub const fn hoist(mut self, hoist: bool) -> Self {
105 self.fields.hoist = Some(hoist);
106
107 self
108 }
109
110 pub const fn icon(mut self, icon: &'a str) -> Self {
118 self.fields.icon = Some(icon);
119
120 self
121 }
122
123 pub const fn mentionable(mut self, mentionable: bool) -> Self {
125 self.fields.mentionable = Some(mentionable);
126
127 self
128 }
129
130 pub const fn name(mut self, name: &'a str) -> Self {
134 self.fields.name = Some(name);
135
136 self
137 }
138
139 pub const fn permissions(mut self, permissions: Permissions) -> Self {
141 self.fields.permissions = Some(permissions);
142
143 self
144 }
145
146 pub const fn unicode_emoji(mut self, unicode_emoji: &'a str) -> Self {
148 self.fields.unicode_emoji = Some(unicode_emoji);
149
150 self
151 }
152}
153
154impl<'a> AuditLogReason<'a> for CreateRole<'a> {
155 fn reason(mut self, reason: &'a str) -> Self {
156 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
157
158 self
159 }
160}
161
162impl IntoFuture for CreateRole<'_> {
163 type Output = Result<Response<Role>, Error>;
164
165 type IntoFuture = ResponseFuture<Role>;
166
167 fn into_future(self) -> Self::IntoFuture {
168 let http = self.http;
169
170 match self.try_into_request() {
171 Ok(request) => http.request(request),
172 Err(source) => ResponseFuture::error(source),
173 }
174 }
175}
176
177impl TryIntoRequest for CreateRole<'_> {
178 fn try_into_request(self) -> Result<Request, Error> {
179 let mut request = Request::builder(&Route::CreateRole {
180 guild_id: self.guild_id.get(),
181 });
182
183 request = request.json(&self.fields);
184
185 if let Some(reason) = self.reason.map_err(Error::validation)? {
186 request = request.headers(request::audit_header(reason)?);
187 }
188
189 request.build()
190 }
191}