twilight_http/request/guild/sticker/
update_guild_sticker.rs

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