twilight_http/request/guild/
update_current_member.rs

1use crate::{
2    client::Client,
3    error::Error,
4    request::{self, AuditLogReason, Nullable, Request, TryIntoRequest},
5    response::{marker::EmptyBody, Response, ResponseFuture},
6    routing::Route,
7};
8use serde::Serialize;
9use std::future::IntoFuture;
10use twilight_model::id::{marker::GuildMarker, Id};
11use twilight_validate::request::{
12    audit_reason as validate_audit_reason, nickname as validate_nickname, ValidationError,
13};
14
15#[derive(Serialize)]
16struct UpdateCurrentMemberFields<'a> {
17    #[serde(skip_serializing_if = "Option::is_none")]
18    nick: Option<Nullable<&'a str>>,
19}
20
21/// Update the user's member in a guild.
22#[must_use = "requests must be configured and executed"]
23pub struct UpdateCurrentMember<'a> {
24    fields: Result<UpdateCurrentMemberFields<'a>, ValidationError>,
25    guild_id: Id<GuildMarker>,
26    http: &'a Client,
27    reason: Result<Option<&'a str>, ValidationError>,
28}
29
30impl<'a> UpdateCurrentMember<'a> {
31    pub(crate) const fn new(http: &'a Client, guild_id: Id<GuildMarker>) -> Self {
32        Self {
33            fields: Ok(UpdateCurrentMemberFields { nick: None }),
34            guild_id,
35            http,
36            reason: Ok(None),
37        }
38    }
39
40    /// Set the current user's nickname.
41    ///
42    /// Set to [`None`] to clear the nickname.
43    ///
44    /// The minimum length is 1 UTF-16 character and the maximum is 32 UTF-16 characters.
45    ///
46    /// # Errors
47    ///
48    /// Returns an error of type [`Nickname`] if the nickname length is too
49    /// short or too long.
50    ///
51    /// [`Nickname`]: twilight_validate::request::ValidationErrorType::Nickname
52    pub fn nick(mut self, nick: Option<&'a str>) -> Self {
53        self.fields = self.fields.and_then(|mut fields| {
54            if let Some(nick) = nick {
55                validate_nickname(nick)?;
56            }
57
58            fields.nick = Some(Nullable(nick));
59
60            Ok(fields)
61        });
62
63        self
64    }
65}
66
67impl<'a> AuditLogReason<'a> for UpdateCurrentMember<'a> {
68    fn reason(mut self, reason: &'a str) -> Self {
69        self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
70
71        self
72    }
73}
74
75impl IntoFuture for UpdateCurrentMember<'_> {
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 UpdateCurrentMember<'_> {
91    fn try_into_request(self) -> Result<Request, Error> {
92        let fields = self.fields.map_err(Error::validation)?;
93        let mut request = Request::builder(&Route::UpdateCurrentMember {
94            guild_id: self.guild_id.get(),
95        })
96        .json(&fields);
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}