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}