Skip to main content

twilight_http/request/guild/sticker/
create_guild_sticker.rs

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