twilight_http/request/channel/
update_channel_permission.rs1use crate::{
2 client::Client,
3 error::Error,
4 request::{self, AuditLogReason, Request, TryIntoRequest},
5 response::{marker::EmptyBody, Response, ResponseFuture},
6 routing::Route,
7};
8use serde::Serialize;
9use std::future::IntoFuture;
10use twilight_model::{
11 guild::Permissions,
12 http::permission_overwrite::{PermissionOverwrite, PermissionOverwriteType},
13 id::{
14 marker::{ChannelMarker, GenericMarker},
15 Id,
16 },
17};
18use twilight_validate::request::{audit_reason as validate_audit_reason, ValidationError};
19
20#[derive(Serialize)]
21struct UpdateChannelPermissionFields {
22 #[serde(skip_serializing_if = "Option::is_none")]
23 allow: Option<Permissions>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 deny: Option<Permissions>,
26 #[serde(rename = "type")]
27 kind: PermissionOverwriteType,
28}
29
30#[must_use = "requests must be configured and executed"]
62pub struct UpdateChannelPermission<'a> {
63 channel_id: Id<ChannelMarker>,
64 fields: UpdateChannelPermissionFields,
65 http: &'a Client,
66 reason: Result<Option<&'a str>, ValidationError>,
67 target_id: Id<GenericMarker>,
68}
69
70impl<'a> UpdateChannelPermission<'a> {
71 pub(crate) const fn new(
72 http: &'a Client,
73 channel_id: Id<ChannelMarker>,
74 permission_overwrite: &PermissionOverwrite,
75 ) -> Self {
76 Self {
77 channel_id,
78 http,
79 fields: UpdateChannelPermissionFields {
80 allow: permission_overwrite.allow,
81 deny: permission_overwrite.deny,
82 kind: permission_overwrite.kind,
83 },
84 reason: Ok(None),
85 target_id: permission_overwrite.id,
86 }
87 }
88}
89
90impl<'a> AuditLogReason<'a> for UpdateChannelPermission<'a> {
91 fn reason(mut self, reason: &'a str) -> Self {
92 self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
93
94 self
95 }
96}
97
98impl IntoFuture for UpdateChannelPermission<'_> {
99 type Output = Result<Response<EmptyBody>, Error>;
100
101 type IntoFuture = ResponseFuture<EmptyBody>;
102
103 fn into_future(self) -> Self::IntoFuture {
104 let http = self.http;
105
106 match self.try_into_request() {
107 Ok(request) => http.request(request),
108 Err(source) => ResponseFuture::error(source),
109 }
110 }
111}
112
113impl TryIntoRequest for UpdateChannelPermission<'_> {
114 fn try_into_request(self) -> Result<Request, Error> {
115 let mut request = Request::builder(&Route::UpdatePermissionOverwrite {
116 channel_id: self.channel_id.get(),
117 target_id: self.target_id.get(),
118 })
119 .json(&self.fields);
120
121 if let Some(reason) = self.reason.map_err(Error::validation)? {
122 request = request.headers(request::audit_header(reason)?);
123 }
124
125 request.build()
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn request() {
135 let permission_overwrite = PermissionOverwrite {
136 allow: None,
137 deny: Some(Permissions::SEND_MESSAGES),
138 id: Id::new(2),
139 kind: PermissionOverwriteType::Member,
140 };
141
142 let client = Client::new("foo".to_owned());
143 let builder = UpdateChannelPermission::new(&client, Id::new(1), &permission_overwrite);
144 let actual = builder
145 .try_into_request()
146 .expect("failed to create request");
147
148 let body = crate::json::to_vec(&UpdateChannelPermissionFields {
149 allow: None,
150 deny: Some(Permissions::SEND_MESSAGES),
151 kind: PermissionOverwriteType::Member,
152 })
153 .expect("failed to serialize payload");
154 let route = Route::UpdatePermissionOverwrite {
155 channel_id: 1,
156 target_id: 2,
157 };
158 let expected = Request::builder(&route).body(body).build().unwrap();
159
160 assert_eq!(expected.body, actual.body);
161 assert_eq!(expected.path, actual.path);
162 }
163}