twilight_model/channel/message/
allowed_mentions.rs

1use crate::{
2    id::{
3        marker::{RoleMarker, UserMarker},
4        Id,
5    },
6    util::is_false,
7};
8use serde::{Deserialize, Serialize};
9
10/// Allowed mentions (pings).
11///
12/// Filters mentions to only ping one's specified here, regardless of the message's content[^1].
13///
14/// Mentions can be clicked to reveal additional context, whilst only requiring an ID to create. See
15/// [Discord Docs/Message Formatting].
16///
17/// [`AllowedMentions::default`] disallows all pings.
18///
19/// [^1]: Messages must still contain mentions, e.g. `@everyone`!
20///
21/// [Discord Docs/Message Formatting]: https://discord.com/developers/docs/reference#message-formatting
22#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
23pub struct AllowedMentions {
24    /// List of allowed mention types.
25    ///
26    /// [`MentionType::Roles`] and [`MentionType::Users`] allows all roles and users to be
27    /// mentioned; they are mutually exclusive with the [`roles`] and [`users`] fields.
28    ///
29    /// [`roles`]: Self::roles
30    /// [`users`]: Self::users
31    #[serde(default)]
32    pub parse: Vec<MentionType>,
33    /// For replies, whether to mention the message author.
34    ///
35    /// Defaults to false.
36    #[serde(default, skip_serializing_if = "is_false")]
37    pub replied_user: bool,
38    /// List of roles to mention.
39    #[serde(default, skip_serializing_if = "Vec::is_empty")]
40    pub roles: Vec<Id<RoleMarker>>,
41    /// List of users to mention.
42    #[serde(default, skip_serializing_if = "Vec::is_empty")]
43    pub users: Vec<Id<UserMarker>>,
44}
45
46/// Allowed mention type.
47#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
48#[non_exhaustive]
49#[serde(rename_all = "lowercase")]
50pub enum MentionType {
51    /// `@everyone` and `@here` mentions.
52    Everyone,
53    /// Role mentions.
54    Roles,
55    /// User mentions.
56    Users,
57}
58
59#[cfg(test)]
60mod tests {
61    use super::{AllowedMentions, MentionType};
62    use crate::id::Id;
63    use serde_test::Token;
64
65    #[test]
66    fn minimal() {
67        let value = AllowedMentions {
68            parse: Vec::new(),
69            users: Vec::new(),
70            roles: Vec::new(),
71            replied_user: false,
72        };
73
74        serde_test::assert_tokens(
75            &value,
76            &[
77                Token::Struct {
78                    name: "AllowedMentions",
79                    len: 1,
80                },
81                Token::Str("parse"),
82                Token::Seq { len: Some(0) },
83                Token::SeqEnd,
84                Token::StructEnd,
85            ],
86        );
87    }
88
89    #[test]
90    fn full() {
91        let value = AllowedMentions {
92            parse: Vec::from([MentionType::Everyone]),
93            users: Vec::from([Id::new(100)]),
94            roles: Vec::from([Id::new(200)]),
95            replied_user: true,
96        };
97
98        serde_test::assert_tokens(
99            &value,
100            &[
101                Token::Struct {
102                    name: "AllowedMentions",
103                    len: 4,
104                },
105                Token::Str("parse"),
106                Token::Seq { len: Some(1) },
107                Token::UnitVariant {
108                    name: "MentionType",
109                    variant: "everyone",
110                },
111                Token::SeqEnd,
112                Token::Str("replied_user"),
113                Token::Bool(true),
114                Token::Str("roles"),
115                Token::Seq { len: Some(1) },
116                Token::NewtypeStruct { name: "Id" },
117                Token::Str("200"),
118                Token::SeqEnd,
119                Token::Str("users"),
120                Token::Seq { len: Some(1) },
121                Token::NewtypeStruct { name: "Id" },
122                Token::Str("100"),
123                Token::SeqEnd,
124                Token::StructEnd,
125            ],
126        );
127    }
128}