Skip to main content

twilight_http/request/guild/sticker/
update_guild_sticker.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    channel::message::sticker::Sticker,
13    id::{
14        Id,
15        marker::{GuildMarker, StickerMarker},
16    },
17};
18use twilight_validate::{
19    request::{ValidationError, audit_reason as validate_audit_reason},
20    sticker::{
21        StickerValidationError, description as validate_description, name as validate_name,
22        tags as validate_tags,
23    },
24};
25
26#[derive(Serialize)]
27struct UpdateGuildStickerFields<'a> {
28    description: Option<&'a str>,
29    name: Option<&'a str>,
30    tags: Option<&'a str>,
31}
32
33/// Updates a sticker in a guild, and returns the updated sticker.
34///
35/// # Examples
36///
37/// ```no_run
38/// use twilight_http::Client;
39/// use twilight_model::id::Id;
40///
41/// # #[tokio::main]
42/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
43/// let client = Client::new("my token".to_owned());
44///
45/// let guild_id = Id::new(1);
46/// let sticker_id = Id::new(2);
47/// let sticker = client
48///     .update_guild_sticker(guild_id, sticker_id)
49///     .description("new description")
50///     .await?
51///     .model()
52///     .await?;
53///
54/// println!("{sticker:#?}");
55/// # Ok(()) }
56/// ```
57#[must_use = "requests must be configured and executed"]
58pub struct UpdateGuildSticker<'a> {
59    fields: Result<UpdateGuildStickerFields<'a>, StickerValidationError>,
60    guild_id: Id<GuildMarker>,
61    http: &'a Client,
62    reason: Result<Option<&'a str>, ValidationError>,
63    sticker_id: Id<StickerMarker>,
64}
65
66impl<'a> UpdateGuildSticker<'a> {
67    pub(crate) const fn new(
68        http: &'a Client,
69        guild_id: Id<GuildMarker>,
70        sticker_id: Id<StickerMarker>,
71    ) -> Self {
72        Self {
73            guild_id,
74            fields: Ok(UpdateGuildStickerFields {
75                description: None,
76                name: None,
77                tags: None,
78            }),
79            http,
80            reason: Ok(None),
81            sticker_id,
82        }
83    }
84
85    /// Set the sticker's description.
86    ///
87    /// # Errors
88    ///
89    /// Returns an error of type [`DescriptionInvalid`] if the length is invalid.
90    ///
91    /// [`DescriptionInvalid`]: twilight_validate::sticker::StickerValidationErrorType::DescriptionInvalid
92    pub fn description(mut self, description: &'a str) -> Self {
93        self.fields = self.fields.and_then(|mut fields| {
94            validate_description(description)?;
95            fields.description = Some(description);
96
97            Ok(fields)
98        });
99
100        self
101    }
102
103    /// Set the sticker's name.
104    ///
105    /// # Errors
106    ///
107    /// Returns an error of type [`NameInvalid`] if the length is invalid.
108    ///
109    /// [`NameInvalid`]: twilight_validate::sticker::StickerValidationErrorType::NameInvalid
110    pub fn name(mut self, name: &'a str) -> Self {
111        self.fields = self.fields.and_then(|mut fields| {
112            validate_name(name)?;
113            fields.name = Some(name);
114
115            Ok(fields)
116        });
117
118        self
119    }
120
121    /// Set the sticker's tags.
122    ///
123    /// # Errors
124    ///
125    /// Returns an error of type [`TagsInvalid`] if the length is invalid.
126    ///
127    /// [`TagsInvalid`]: twilight_validate::sticker::StickerValidationErrorType::TagsInvalid
128    pub fn tags(mut self, tags: &'a str) -> Self {
129        self.fields = self.fields.and_then(|mut fields| {
130            validate_tags(tags)?;
131            fields.tags = Some(tags);
132
133            Ok(fields)
134        });
135
136        self
137    }
138}
139
140impl<'a> AuditLogReason<'a> for UpdateGuildSticker<'a> {
141    fn reason(mut self, reason: &'a str) -> Self {
142        self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
143
144        self
145    }
146}
147
148#[cfg(not(target_os = "wasi"))]
149impl IntoFuture for UpdateGuildSticker<'_> {
150    type Output = Result<Response<Sticker>, Error>;
151
152    type IntoFuture = ResponseFuture<Sticker>;
153
154    fn into_future(self) -> Self::IntoFuture {
155        let http = self.http;
156
157        match self.try_into_request() {
158            Ok(request) => http.request(request),
159            Err(source) => ResponseFuture::error(source),
160        }
161    }
162}
163
164impl TryIntoRequest for UpdateGuildSticker<'_> {
165    fn try_into_request(self) -> Result<Request, Error> {
166        let fields = self.fields.map_err(Error::validation)?;
167
168        let mut request = Request::builder(&Route::UpdateGuildSticker {
169            guild_id: self.guild_id.get(),
170            sticker_id: self.sticker_id.get(),
171        })
172        .json(&fields);
173
174        if let Ok(Some(reason)) = self.reason {
175            request = request.headers(request::audit_header(reason)?);
176        }
177
178        request.build()
179    }
180}