twilight_http/request/guild/ban/
create_ban.rs1#[cfg(not(target_os = "wasi"))]
2use crate::response::{Response, ResponseFuture, marker::EmptyBody};
3use crate::{
4 client::Client,
5 error::Error,
6 request::{self, AuditLogReason, Request, TryIntoRequest},
7 routing::Route,
8};
9use serde::Serialize;
10use std::future::IntoFuture;
11use twilight_model::id::{
12 Id,
13 marker::{GuildMarker, UserMarker},
14};
15use twilight_validate::request::{
16 ValidationError, audit_reason as validate_audit_reason,
17 create_guild_ban_delete_message_seconds as validate_create_guild_ban_delete_message_seconds,
18};
19
20#[derive(Serialize)]
21struct CreateBanFields {
22 delete_message_seconds: Option<u32>,
24}
25
26#[must_use = "requests must be configured and executed"]
52pub struct CreateBan<'a> {
53 fields: Result<CreateBanFields, ValidationError>,
54 guild_id: Id<GuildMarker>,
55 http: &'a Client,
56 reason: Result<Option<&'a str>, ValidationError>,
57 user_id: Id<UserMarker>,
58}
59
60impl<'a> CreateBan<'a> {
61 pub(crate) const fn new(
62 http: &'a Client,
63 guild_id: Id<GuildMarker>,
64 user_id: Id<UserMarker>,
65 ) -> Self {
66 Self {
67 fields: Ok(CreateBanFields {
68 delete_message_seconds: None,
69 }),
70 guild_id,
71 http,
72 reason: Ok(None),
73 user_id,
74 }
75 }
76
77 pub fn delete_message_seconds(mut self, seconds: u32) -> Self {
88 self.fields = self.fields.and_then(|mut fields| {
89 validate_create_guild_ban_delete_message_seconds(seconds)?;
90 fields.delete_message_seconds = Some(seconds);
91
92 Ok(fields)
93 });
94
95 self
96 }
97}
98
99impl<'a> AuditLogReason<'a> for CreateBan<'a> {
100 fn reason(mut self, reason: &'a str) -> Self {
101 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
102
103 self
104 }
105}
106
107#[cfg(not(target_os = "wasi"))]
108impl IntoFuture for CreateBan<'_> {
109 type Output = Result<Response<EmptyBody>, Error>;
110
111 type IntoFuture = ResponseFuture<EmptyBody>;
112
113 fn into_future(self) -> Self::IntoFuture {
114 let http = self.http;
115
116 match self.try_into_request() {
117 Ok(request) => http.request(request),
118 Err(source) => ResponseFuture::error(source),
119 }
120 }
121}
122
123impl TryIntoRequest for CreateBan<'_> {
124 fn try_into_request(self) -> Result<Request, Error> {
125 let fields = self.fields.map_err(Error::validation)?;
126 let mut request = Request::builder(&Route::CreateBan {
127 guild_id: self.guild_id.get(),
128 user_id: self.user_id.get(),
129 })
130 .json(&fields);
131
132 if let Some(reason) = self.reason.map_err(Error::validation)? {
133 request = request.headers(request::audit_header(reason)?);
134 }
135
136 request.build()
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use crate::{
143 client::Client,
144 request::{AuditLogReason, REASON_HEADER_NAME, TryIntoRequest},
145 };
146 use http::header::HeaderValue;
147 use std::error::Error;
148 use twilight_http_ratelimiting::Method;
149 use twilight_model::id::{
150 Id,
151 marker::{GuildMarker, UserMarker},
152 };
153
154 #[test]
155 fn request() -> Result<(), Box<dyn Error>> {
156 const GUILD_ID: Id<GuildMarker> = Id::new(1);
157 const REASON: &str = "spam";
158 const USER_ID: Id<UserMarker> = Id::new(2);
159
160 let client = Client::new(String::new());
161 let request = client
162 .create_ban(GUILD_ID, USER_ID)
163 .delete_message_seconds(100)
164 .reason(REASON)
165 .try_into_request()?;
166
167 assert!(request.body().is_some());
168 assert!(request.form().is_none());
169 assert_eq!(Method::Put, request.method());
170
171 let header = HeaderValue::from_static(REASON);
172 assert!(matches!(
173 request.headers(),
174 Some(map)
175 if map.len() == 1 && map.get(REASON_HEADER_NAME) == Some(&header)));
176 assert!(request.use_authorization_token());
177
178 Ok(())
179 }
180}