serenity/builder/
mod.rs

1//! A set of builders used to make using methods on certain structs simpler to use.
2//!
3//! These are used when not all parameters are required, all parameters are optional, and/or sane
4//! default values for required parameters can be applied by a builder.
5
6// Option<Option<T>> is required for fields that are
7// #[serde(skip_serializing_if = "Option::is_none")]
8#![allow(clippy::option_option)]
9
10#[cfg(feature = "http")]
11use crate::http::CacheHttp;
12#[cfg(feature = "http")]
13use crate::internal::prelude::*;
14
15/// Common trait for all HTTP request builders in this module.
16#[cfg(feature = "http")]
17#[async_trait::async_trait]
18pub trait Builder {
19    /// Additional data that's only required when sending a request off to the API.
20    type Context<'ctx>;
21    type Built;
22    /// Serializes a builder's fields and sends the request off the API, returning the response.
23    async fn execute(
24        self,
25        cache_http: impl CacheHttp,
26        ctx: Self::Context<'_>,
27    ) -> Result<Self::Built>;
28}
29
30#[cfg(feature = "http")]
31pub(crate) fn check_overflow(len: usize, max: usize) -> StdResult<(), usize> {
32    if len > max {
33        Err(len - max)
34    } else {
35        Ok(())
36    }
37}
38
39mod add_member;
40mod bot_auth_parameters;
41mod create_allowed_mentions;
42mod create_attachment;
43mod create_channel;
44mod create_command;
45mod create_command_permission;
46mod create_components;
47mod create_embed;
48mod create_forum_post;
49mod create_forum_tag;
50mod create_interaction_response;
51mod create_interaction_response_followup;
52mod create_invite;
53mod create_message;
54pub mod create_poll;
55mod create_scheduled_event;
56mod create_stage_instance;
57mod create_sticker;
58mod create_thread;
59mod create_webhook;
60mod edit_automod_rule;
61mod edit_channel;
62mod edit_guild;
63mod edit_guild_welcome_screen;
64mod edit_guild_widget;
65mod edit_interaction_response;
66mod edit_member;
67mod edit_message;
68mod edit_profile;
69mod edit_role;
70mod edit_scheduled_event;
71mod edit_stage_instance;
72mod edit_sticker;
73mod edit_thread;
74mod edit_voice_state;
75mod edit_webhook;
76mod edit_webhook_message;
77mod execute_webhook;
78mod get_entitlements;
79mod get_messages;
80
81pub use add_member::*;
82pub use bot_auth_parameters::*;
83pub use create_allowed_mentions::*;
84pub use create_attachment::*;
85pub use create_channel::*;
86pub use create_command::*;
87pub use create_command_permission::*;
88pub use create_components::*;
89pub use create_embed::*;
90pub use create_forum_post::*;
91pub use create_forum_tag::*;
92pub use create_interaction_response::*;
93pub use create_interaction_response_followup::*;
94pub use create_invite::*;
95pub use create_message::*;
96pub use create_poll::{CreatePoll, CreatePollAnswer};
97pub use create_scheduled_event::*;
98pub use create_stage_instance::*;
99pub use create_sticker::*;
100pub use create_thread::*;
101pub use create_webhook::*;
102pub use edit_automod_rule::*;
103pub use edit_channel::*;
104pub use edit_guild::*;
105pub use edit_guild_welcome_screen::*;
106pub use edit_guild_widget::*;
107pub use edit_interaction_response::*;
108pub use edit_member::*;
109pub use edit_message::*;
110pub use edit_profile::*;
111pub use edit_role::*;
112pub use edit_scheduled_event::*;
113pub use edit_stage_instance::*;
114pub use edit_sticker::*;
115pub use edit_thread::*;
116pub use edit_voice_state::*;
117pub use edit_webhook::*;
118pub use edit_webhook_message::*;
119pub use execute_webhook::*;
120pub use get_entitlements::*;
121pub use get_messages::*;
122
123macro_rules! button_and_select_menu_convenience_methods {
124    ($self:ident $(. $components_path:tt)+) => {
125        /// Adds a clickable button to this message.
126        ///
127        /// Convenience method that wraps [`Self::components`]. Arranges buttons in action rows
128        /// automatically.
129        pub fn button(mut $self, button: super::CreateButton) -> Self {
130            let rows = $self$(.$components_path)+.get_or_insert_with(Vec::new);
131            let row_with_space_left = rows.last_mut().and_then(|row| match row {
132                super::CreateActionRow::Buttons(buttons) if buttons.len() < 5 => Some(buttons),
133                _ => None,
134            });
135            match row_with_space_left {
136                Some(row) => row.push(button),
137                None => rows.push(super::CreateActionRow::Buttons(vec![button])),
138            }
139            $self
140        }
141
142        /// Adds an interactive select menu to this message.
143        ///
144        /// Convenience method that wraps [`Self::components`].
145        pub fn select_menu(mut $self, select_menu: super::CreateSelectMenu) -> Self {
146            $self$(.$components_path)+
147                .get_or_insert_with(Vec::new)
148                .push(super::CreateActionRow::SelectMenu(select_menu));
149            $self
150        }
151    };
152}
153
154use button_and_select_menu_convenience_methods;