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