twilight_http/request/guild/member/
add_role_to_member.rs

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