twilight_model/channel/message/
mention.rs1use crate::{
2 guild::PartialMember,
3 id::{marker::UserMarker, Id},
4 user::{self, DiscriminatorDisplay, UserFlags},
5 util::image_hash::ImageHash,
6};
7use serde::{Deserialize, Serialize};
8
9#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
11pub struct Mention {
12 pub avatar: Option<ImageHash>,
14 #[serde(default)]
16 pub bot: bool,
17 #[serde(with = "user::discriminator")]
25 pub discriminator: u16,
26 pub id: Id<UserMarker>,
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub member: Option<PartialMember>,
31 #[serde(rename = "username")]
32 pub name: String,
34 pub public_flags: UserFlags,
36}
37
38impl Mention {
39 pub const fn discriminator(&self) -> DiscriminatorDisplay {
43 DiscriminatorDisplay::new(self.discriminator)
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::{Mention, PartialMember, UserFlags};
50 use crate::{
51 guild::MemberFlags,
52 id::Id,
53 util::datetime::{Timestamp, TimestampParseError},
54 };
55 use serde_test::Token;
56 use std::str::FromStr;
57
58 #[test]
59 fn mention_without_member() {
60 let value = Mention {
61 avatar: None,
62 bot: false,
63 discriminator: 1,
64 id: Id::new(1),
65 member: None,
66 name: "foo".to_owned(),
67 public_flags: UserFlags::empty(),
68 };
69
70 serde_test::assert_tokens(
71 &value,
72 &[
73 Token::Struct {
74 name: "Mention",
75 len: 6,
76 },
77 Token::Str("avatar"),
78 Token::None,
79 Token::Str("bot"),
80 Token::Bool(false),
81 Token::Str("discriminator"),
82 Token::Str("0001"),
83 Token::Str("id"),
84 Token::NewtypeStruct { name: "Id" },
85 Token::Str("1"),
86 Token::Str("username"),
87 Token::Str("foo"),
88 Token::Str("public_flags"),
89 Token::U64(0),
90 Token::StructEnd,
91 ],
92 );
93 }
94
95 #[test]
96 fn mention_with_member() -> Result<(), TimestampParseError> {
97 let joined_at = Some(Timestamp::from_str("2015-04-26T06:26:56.936000+00:00")?);
98 let flags = MemberFlags::BYPASSES_VERIFICATION | MemberFlags::DID_REJOIN;
99
100 let value = Mention {
101 avatar: None,
102 bot: false,
103 discriminator: 1,
104 id: Id::new(1),
105 member: Some(PartialMember {
106 avatar: None,
107 communication_disabled_until: None,
108 deaf: false,
109 flags,
110 joined_at,
111 mute: true,
112 nick: Some("bar".to_owned()),
113 permissions: None,
114 premium_since: None,
115 roles: Vec::new(),
116 user: None,
117 }),
118 name: "foo".to_owned(),
119 public_flags: UserFlags::empty(),
120 };
121
122 serde_test::assert_tokens(
123 &value,
124 &[
125 Token::Struct {
126 name: "Mention",
127 len: 7,
128 },
129 Token::Str("avatar"),
130 Token::None,
131 Token::Str("bot"),
132 Token::Bool(false),
133 Token::Str("discriminator"),
134 Token::Str("0001"),
135 Token::Str("id"),
136 Token::NewtypeStruct { name: "Id" },
137 Token::Str("1"),
138 Token::Str("member"),
139 Token::Some,
140 Token::Struct {
141 name: "PartialMember",
142 len: 8,
143 },
144 Token::Str("communication_disabled_until"),
145 Token::None,
146 Token::Str("deaf"),
147 Token::Bool(false),
148 Token::Str("flags"),
149 Token::U64(flags.bits()),
150 Token::Str("joined_at"),
151 Token::Some,
152 Token::Str("2015-04-26T06:26:56.936000+00:00"),
153 Token::Str("mute"),
154 Token::Bool(true),
155 Token::Str("nick"),
156 Token::Some,
157 Token::Str("bar"),
158 Token::Str("roles"),
159 Token::Seq { len: Some(0) },
160 Token::SeqEnd,
161 Token::Str("user"),
162 Token::None,
163 Token::StructEnd,
164 Token::Str("username"),
165 Token::Str("foo"),
166 Token::Str("public_flags"),
167 Token::U64(0),
168 Token::StructEnd,
169 ],
170 );
171 Ok(())
172 }
173}