Skip to main content

twilight_http/request/guild/emoji/
update_emoji.rs

1#[cfg(not(target_os = "wasi"))]
2use crate::response::{Response, ResponseFuture};
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::{
12    guild::Emoji,
13    id::{
14        Id,
15        marker::{EmojiMarker, GuildMarker, RoleMarker},
16    },
17};
18use twilight_validate::request::{ValidationError, audit_reason as validate_audit_reason};
19
20#[derive(Serialize)]
21struct UpdateEmojiFields<'a> {
22    #[serde(skip_serializing_if = "Option::is_none")]
23    name: Option<&'a str>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    roles: Option<&'a [Id<RoleMarker>]>,
26}
27
28/// Update an emoji in a guild, by id.
29#[must_use = "requests must be configured and executed"]
30pub struct UpdateEmoji<'a> {
31    emoji_id: Id<EmojiMarker>,
32    fields: UpdateEmojiFields<'a>,
33    guild_id: Id<GuildMarker>,
34    http: &'a Client,
35    reason: Result<Option<&'a str>, ValidationError>,
36}
37
38impl<'a> UpdateEmoji<'a> {
39    pub(crate) const fn new(
40        http: &'a Client,
41        guild_id: Id<GuildMarker>,
42        emoji_id: Id<EmojiMarker>,
43    ) -> Self {
44        Self {
45            fields: UpdateEmojiFields {
46                name: None,
47                roles: None,
48            },
49            emoji_id,
50            guild_id,
51            http,
52            reason: Ok(None),
53        }
54    }
55
56    /// Change the name of the emoji.
57    pub const fn name(mut self, name: &'a str) -> Self {
58        self.fields.name = Some(name);
59
60        self
61    }
62
63    /// Change the roles that the emoji is whitelisted to.
64    pub const fn roles(mut self, roles: &'a [Id<RoleMarker>]) -> Self {
65        self.fields.roles = Some(roles);
66
67        self
68    }
69}
70
71impl<'a> AuditLogReason<'a> for UpdateEmoji<'a> {
72    fn reason(mut self, reason: &'a str) -> Self {
73        self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
74
75        self
76    }
77}
78
79#[cfg(not(target_os = "wasi"))]
80impl IntoFuture for UpdateEmoji<'_> {
81    type Output = Result<Response<Emoji>, Error>;
82
83    type IntoFuture = ResponseFuture<Emoji>;
84
85    fn into_future(self) -> Self::IntoFuture {
86        let http = self.http;
87
88        match self.try_into_request() {
89            Ok(request) => http.request(request),
90            Err(source) => ResponseFuture::error(source),
91        }
92    }
93}
94
95impl TryIntoRequest for UpdateEmoji<'_> {
96    fn try_into_request(self) -> Result<Request, Error> {
97        let mut request = Request::builder(&Route::UpdateEmoji {
98            emoji_id: self.emoji_id.get(),
99            guild_id: self.guild_id.get(),
100        });
101
102        request = request.json(&self.fields);
103
104        if let Some(reason) = self.reason.map_err(Error::validation)? {
105            request = request.headers(request::audit_header(reason)?);
106        }
107
108        request.build()
109    }
110}