serenity/builder/create_allowed_mentions.rs
1use arrayvec::ArrayVec;
2use serde::{Deserialize, Serialize};
3
4use crate::model::prelude::*;
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
7#[serde(rename_all = "lowercase")]
8enum ParseValue {
9 Everyone,
10 Users,
11 Roles,
12}
13
14enum ParseAction {
15 Remove,
16 Insert,
17}
18
19impl ParseAction {
20 fn from_allow(allow: bool) -> Self {
21 if allow {
22 Self::Insert
23 } else {
24 Self::Remove
25 }
26 }
27}
28
29/// A builder to manage the allowed mentions on a message, used by the [`ChannelId::send_message`]
30/// and [`ChannelId::edit_message`] methods.
31///
32/// # Examples
33///
34/// ```rust,no_run
35/// # use serenity::builder::CreateMessage;
36/// # use serenity::model::channel::Message;
37/// #
38/// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
39/// use serenity::builder::CreateAllowedMentions as Am;
40///
41/// // Mention only the user 110372470472613888
42/// # let m = CreateMessage::new();
43/// m.allowed_mentions(Am::new().users(vec![110372470472613888]));
44///
45/// // Mention all users and the role 182894738100322304
46/// # let m = CreateMessage::new();
47/// m.allowed_mentions(Am::new().all_users(true).roles(vec![182894738100322304]));
48///
49/// // Mention all roles and nothing else
50/// # let m = CreateMessage::new();
51/// m.allowed_mentions(Am::new().all_roles(true));
52///
53/// // Mention all roles and users, but not everyone
54/// # let m = CreateMessage::new();
55/// m.allowed_mentions(Am::new().all_users(true).all_roles(true));
56///
57/// // Mention everyone and the users 182891574139682816, 110372470472613888
58/// # let m = CreateMessage::new();
59/// m.allowed_mentions(
60/// Am::new().everyone(true).users(vec![182891574139682816, 110372470472613888]),
61/// );
62///
63/// // Mention everyone and the message author.
64/// # let m = CreateMessage::new();
65/// # let msg: Message = unimplemented!();
66/// m.allowed_mentions(Am::new().everyone(true).users(vec![msg.author.id]));
67/// # Ok(())
68/// # }
69/// ```
70///
71/// [Discord docs](https://discord.com/developers/docs/resources/channel#allowed-mentions-object).
72#[derive(Clone, Debug, Default, Serialize, PartialEq)]
73#[must_use]
74pub struct CreateAllowedMentions {
75 parse: ArrayVec<ParseValue, 3>,
76 users: Vec<UserId>,
77 roles: Vec<RoleId>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 replied_user: Option<bool>,
80}
81
82impl CreateAllowedMentions {
83 /// Equivalent to [`Self::default`].
84 pub fn new() -> Self {
85 Self::default()
86 }
87
88 fn handle_parse_unique(mut self, value: ParseValue, action: ParseAction) -> Self {
89 let existing_pos = self.parse.iter().position(|p| *p == value);
90 match (existing_pos, action) {
91 (Some(pos), ParseAction::Remove) => drop(self.parse.swap_remove(pos)),
92 (None, ParseAction::Insert) => self.parse.push(value),
93 _ => {},
94 };
95
96 self
97 }
98
99 /// Toggles mentions for all users. Overrides [`Self::users`] if it was previously set.
100 pub fn all_users(self, allow: bool) -> Self {
101 self.handle_parse_unique(ParseValue::Users, ParseAction::from_allow(allow))
102 }
103
104 /// Toggles mentions for all roles. Overrides [`Self::roles`] if it was previously set.
105 pub fn all_roles(self, allow: bool) -> Self {
106 self.handle_parse_unique(ParseValue::Roles, ParseAction::from_allow(allow))
107 }
108
109 /// Toggles @everyone and @here mentions.
110 pub fn everyone(self, allow: bool) -> Self {
111 self.handle_parse_unique(ParseValue::Everyone, ParseAction::from_allow(allow))
112 }
113
114 /// Sets the *specific* users that will be allowed mentionable.
115 #[inline]
116 pub fn users(mut self, users: impl IntoIterator<Item = impl Into<UserId>>) -> Self {
117 self.users = users.into_iter().map(Into::into).collect();
118 self
119 }
120
121 /// Clear the list of mentionable users.
122 #[inline]
123 pub fn empty_users(mut self) -> Self {
124 self.users.clear();
125 self
126 }
127
128 /// Sets the *specific* roles that will be allowed mentionable.
129 #[inline]
130 pub fn roles(mut self, roles: impl IntoIterator<Item = impl Into<RoleId>>) -> Self {
131 self.roles = roles.into_iter().map(Into::into).collect();
132 self
133 }
134
135 /// Clear the list of mentionable roles.
136 #[inline]
137 pub fn empty_roles(mut self) -> Self {
138 self.roles.clear();
139 self
140 }
141
142 /// Makes the reply mention/ping the user.
143 #[inline]
144 pub fn replied_user(mut self, mention_user: bool) -> Self {
145 self.replied_user = Some(mention_user);
146 self
147 }
148}