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},
12 id::{marker::GuildMarker, Id},
13};
14use twilight_validate::request::{audit_reason as validate_audit_reason, ValidationError};
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 hoist: Option<bool>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 icon: Option<&'a [u8]>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 mentionable: Option<bool>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 name: Option<&'a str>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 permissions: Option<Permissions>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 unicode_emoji: Option<&'a str>,
32}
33
34#[must_use = "requests must be configured and executed"]
55pub struct CreateRole<'a> {
56 fields: CreateRoleFields<'a>,
57 guild_id: Id<GuildMarker>,
58 http: &'a Client,
59 reason: Result<Option<&'a str>, ValidationError>,
60}
61
62impl<'a> CreateRole<'a> {
63 pub(crate) const fn new(http: &'a Client, guild_id: Id<GuildMarker>) -> Self {
64 Self {
65 fields: CreateRoleFields {
66 color: None,
67 hoist: None,
68 icon: None,
69 mentionable: None,
70 name: None,
71 permissions: None,
72 unicode_emoji: None,
73 },
74 guild_id,
75 http,
76 reason: Ok(None),
77 }
78 }
79
80 pub const fn color(mut self, color: u32) -> Self {
88 self.fields.color = Some(color);
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: &'a [u8]) -> Self {
108 self.fields.icon = Some(icon);
109
110 self
111 }
112
113 pub const fn mentionable(mut self, mentionable: bool) -> Self {
115 self.fields.mentionable = Some(mentionable);
116
117 self
118 }
119
120 pub const fn name(mut self, name: &'a str) -> Self {
124 self.fields.name = Some(name);
125
126 self
127 }
128
129 pub const fn permissions(mut self, permissions: Permissions) -> Self {
131 self.fields.permissions = Some(permissions);
132
133 self
134 }
135
136 pub const fn unicode_emoji(mut self, unicode_emoji: &'a str) -> Self {
138 self.fields.unicode_emoji = Some(unicode_emoji);
139
140 self
141 }
142}
143
144impl<'a> AuditLogReason<'a> for CreateRole<'a> {
145 fn reason(mut self, reason: &'a str) -> Self {
146 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
147
148 self
149 }
150}
151
152impl IntoFuture for CreateRole<'_> {
153 type Output = Result<Response<Role>, Error>;
154
155 type IntoFuture = ResponseFuture<Role>;
156
157 fn into_future(self) -> Self::IntoFuture {
158 let http = self.http;
159
160 match self.try_into_request() {
161 Ok(request) => http.request(request),
162 Err(source) => ResponseFuture::error(source),
163 }
164 }
165}
166
167impl TryIntoRequest for CreateRole<'_> {
168 fn try_into_request(self) -> Result<Request, Error> {
169 let mut request = Request::builder(&Route::CreateRole {
170 guild_id: self.guild_id.get(),
171 });
172
173 request = request.json(&self.fields);
174
175 if let Some(reason) = self.reason.map_err(Error::validation)? {
176 request = request.headers(request::audit_header(reason)?);
177 }
178
179 request.build()
180 }
181}