Skip to main content

twilight_http/request/guild/member/
add_role_to_member.rs

1#[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 std::future::IntoFuture;
10use twilight_model::id::{
11    Id,
12    marker::{GuildMarker, RoleMarker, UserMarker},
13};
14use twilight_validate::request::{ValidationError, audit_reason as validate_audit_reason};
15
16/// Add a role to a member in a guild.
17///
18/// # Examples
19///
20/// In guild `1`, add role `2` to user `3`, for the reason `"test"`:
21///
22/// ```no_run
23/// use twilight_http::{Client, request::AuditLogReason};
24/// use twilight_model::id::Id;
25///
26/// # #[tokio::main]
27/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
28/// let client = Client::new("my token".to_owned());
29///
30/// let guild_id = Id::new(1);
31/// let role_id = Id::new(2);
32/// let user_id = Id::new(3);
33///
34/// client
35///     .add_guild_member_role(guild_id, user_id, role_id)
36///     .reason("test")
37///     .await?;
38/// # Ok(()) }
39/// ```
40#[must_use = "requests must be configured and executed"]
41pub struct AddRoleToMember<'a> {
42    guild_id: Id<GuildMarker>,
43    http: &'a Client,
44    role_id: Id<RoleMarker>,
45    user_id: Id<UserMarker>,
46    reason: Result<Option<&'a str>, ValidationError>,
47}
48
49impl<'a> AddRoleToMember<'a> {
50    pub(crate) const fn new(
51        http: &'a Client,
52        guild_id: Id<GuildMarker>,
53        user_id: Id<UserMarker>,
54        role_id: Id<RoleMarker>,
55    ) -> Self {
56        Self {
57            guild_id,
58            http,
59            role_id,
60            user_id,
61            reason: Ok(None),
62        }
63    }
64}
65
66impl<'a> AuditLogReason<'a> for AddRoleToMember<'a> {
67    fn reason(mut self, reason: &'a str) -> Self {
68        self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
69
70        self
71    }
72}
73
74#[cfg(not(target_os = "wasi"))]
75impl IntoFuture for AddRoleToMember<'_> {
76    type Output = Result<Response<EmptyBody>, Error>;
77
78    type IntoFuture = ResponseFuture<EmptyBody>;
79
80    fn into_future(self) -> Self::IntoFuture {
81        let http = self.http;
82
83        match self.try_into_request() {
84            Ok(request) => http.request(request),
85            Err(source) => ResponseFuture::error(source),
86        }
87    }
88}
89
90impl TryIntoRequest for AddRoleToMember<'_> {
91    fn try_into_request(self) -> Result<Request, Error> {
92        let mut request = Request::builder(&Route::AddMemberRole {
93            guild_id: self.guild_id.get(),
94            role_id: self.role_id.get(),
95            user_id: self.user_id.get(),
96        });
97
98        if let Some(reason) = self.reason.map_err(Error::validation)? {
99            request = request.headers(request::audit_header(reason)?);
100        }
101
102        request.build()
103    }
104}