Skip to main content

twilight_http/request/template/
create_template.rs

1#[cfg(not(target_os = "wasi"))]
2use crate::response::{Response, ResponseFuture};
3use crate::{
4    client::Client,
5    error::Error,
6    request::{Request, TryIntoRequest},
7    routing::Route,
8};
9use serde::Serialize;
10use std::future::IntoFuture;
11use twilight_model::{
12    guild::template::Template,
13    id::{Id, marker::GuildMarker},
14};
15use twilight_validate::request::{
16    ValidationError, template_description as validate_template_description,
17    template_name as validate_template_name,
18};
19
20#[derive(Serialize)]
21struct CreateTemplateFields<'a> {
22    name: &'a str,
23    description: Option<&'a str>,
24}
25
26/// Create a template from the current state of the guild.
27///
28/// Requires the `MANAGE_GUILD` permission. The name must be at least 1 and at
29/// most 100 characters in length.
30///
31/// # Errors
32///
33/// Returns an error of type [`TemplateName`] if the name length is too short or
34/// too long.
35///
36/// [`TemplateName`]: twilight_validate::request::ValidationErrorType::TemplateName
37#[must_use = "requests must be configured and executed"]
38pub struct CreateTemplate<'a> {
39    fields: Result<CreateTemplateFields<'a>, ValidationError>,
40    guild_id: Id<GuildMarker>,
41    http: &'a Client,
42}
43
44impl<'a> CreateTemplate<'a> {
45    pub(crate) fn new(http: &'a Client, guild_id: Id<GuildMarker>, name: &'a str) -> Self {
46        let fields = Ok(CreateTemplateFields {
47            name,
48            description: None,
49        })
50        .and_then(|fields| {
51            validate_template_name(name)?;
52
53            Ok(fields)
54        });
55
56        Self {
57            fields,
58            guild_id,
59            http,
60        }
61    }
62
63    /// Set the template's description.
64    ///
65    /// This must be less than or equal to 120 characters in length.
66    ///
67    /// # Errors
68    ///
69    /// Returns an error of type [`TemplateDescription`] if the name length is
70    /// too short or too long.
71    ///
72    /// [`TemplateDescription`]: twilight_validate::request::ValidationErrorType::TemplateDescription
73    pub fn description(mut self, description: &'a str) -> Self {
74        self.fields = self.fields.and_then(|mut fields| {
75            validate_template_description(description)?;
76
77            fields.description.replace(description);
78
79            Ok(fields)
80        });
81
82        self
83    }
84}
85
86#[cfg(not(target_os = "wasi"))]
87impl IntoFuture for CreateTemplate<'_> {
88    type Output = Result<Response<Template>, Error>;
89
90    type IntoFuture = ResponseFuture<Template>;
91
92    fn into_future(self) -> Self::IntoFuture {
93        let http = self.http;
94
95        match self.try_into_request() {
96            Ok(request) => http.request(request),
97            Err(source) => ResponseFuture::error(source),
98        }
99    }
100}
101
102impl TryIntoRequest for CreateTemplate<'_> {
103    fn try_into_request(self) -> Result<Request, Error> {
104        let fields = self.fields.map_err(Error::validation)?;
105
106        Request::builder(&Route::CreateTemplate {
107            guild_id: self.guild_id.get(),
108        })
109        .json(&fields)
110        .build()
111    }
112}