twilight_http/request/guild/sticker/
create_guild_sticker.rs

1use crate::{
2    client::Client,
3    error::Error,
4    request::{multipart::Form, AuditLogReason, Request, TryIntoRequest},
5    response::{Response, ResponseFuture},
6    routing::Route,
7};
8use std::future::IntoFuture;
9use twilight_model::{
10    channel::message::Sticker,
11    id::{marker::GuildMarker, Id},
12};
13use twilight_validate::{
14    request::{audit_reason as validate_audit_reason, ValidationError},
15    sticker::{
16        description as validate_description, name as validate_name, tags as validate_tags,
17        StickerValidationError,
18    },
19};
20
21struct CreateGuildStickerFields<'a> {
22    description: &'a str,
23    file: &'a [u8],
24    name: &'a str,
25    tags: &'a str,
26}
27
28/// Creates a sticker in a guild, and returns the created sticker.
29///
30/// # Examples
31///
32/// ```no_run
33/// use twilight_http::Client;
34/// use twilight_model::id::Id;
35///
36/// # #[tokio::main]
37/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
38/// let client = Client::new("my token".to_owned());
39///
40/// let guild_id = Id::new(1);
41/// let sticker = client
42///     .create_guild_sticker(
43///         guild_id,
44///         &"sticker name",
45///         &"sticker description",
46///         &"sticker,tags",
47///         &[23, 23, 23, 23],
48///     )
49///     .await?
50///     .model()
51///     .await?;
52///
53/// println!("{sticker:#?}");
54/// # Ok(()) }
55/// ```
56pub struct CreateGuildSticker<'a> {
57    fields: Result<CreateGuildStickerFields<'a>, StickerValidationError>,
58    guild_id: Id<GuildMarker>,
59    http: &'a Client,
60    reason: Result<Option<&'a str>, ValidationError>,
61}
62
63impl<'a> CreateGuildSticker<'a> {
64    pub(crate) fn new(
65        http: &'a Client,
66        guild_id: Id<GuildMarker>,
67        name: &'a str,
68        description: &'a str,
69        tags: &'a str,
70        file: &'a [u8],
71    ) -> Self {
72        let fields = Ok(CreateGuildStickerFields {
73            description,
74            file,
75            name,
76            tags,
77        })
78        .and_then(|fields| {
79            validate_description(description)?;
80            validate_name(name)?;
81            validate_tags(tags)?;
82
83            Ok(fields)
84        });
85
86        Self {
87            fields,
88            guild_id,
89            http,
90            reason: Ok(None),
91        }
92    }
93}
94
95impl<'a> AuditLogReason<'a> for CreateGuildSticker<'a> {
96    fn reason(mut self, reason: &'a str) -> Self {
97        self.reason = validate_audit_reason(reason).and(Ok(Some(reason)));
98
99        self
100    }
101}
102
103impl IntoFuture for CreateGuildSticker<'_> {
104    type Output = Result<Response<Sticker>, Error>;
105
106    type IntoFuture = ResponseFuture<Sticker>;
107
108    fn into_future(self) -> Self::IntoFuture {
109        let http = self.http;
110
111        match self.try_into_request() {
112            Ok(request) => http.request(request),
113            Err(source) => ResponseFuture::error(source),
114        }
115    }
116}
117
118impl TryIntoRequest for CreateGuildSticker<'_> {
119    fn try_into_request(self) -> Result<Request, Error> {
120        let fields = self.fields.map_err(Error::validation)?;
121        let mut request = Request::builder(&Route::CreateGuildSticker {
122            guild_id: self.guild_id.get(),
123        });
124
125        let form = Form::new()
126            .part(b"description", fields.description.as_bytes())
127            .part(b"file", fields.file)
128            .part(b"name", fields.name.as_bytes())
129            .part(b"tags", fields.tags.as_bytes());
130
131        request = request.form(form);
132
133        request.build()
134    }
135}