twilight_model/channel/message/
mention.rs1use crate::{
2 guild::PartialMember,
3 id::{Id, marker::UserMarker},
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 avatar_decoration_data: None,
108 banner: None,
109 communication_disabled_until: None,
110 deaf: false,
111 flags,
112 joined_at,
113 mute: true,
114 nick: Some("bar".to_owned()),
115 permissions: None,
116 premium_since: None,
117 roles: Vec::new(),
118 user: None,
119 }),
120 name: "foo".to_owned(),
121 public_flags: UserFlags::empty(),
122 };
123
124 serde_test::assert_tokens(
125 &value,
126 &[
127 Token::Struct {
128 name: "Mention",
129 len: 7,
130 },
131 Token::Str("avatar"),
132 Token::None,
133 Token::Str("bot"),
134 Token::Bool(false),
135 Token::Str("discriminator"),
136 Token::Str("0001"),
137 Token::Str("id"),
138 Token::NewtypeStruct { name: "Id" },
139 Token::Str("1"),
140 Token::Str("member"),
141 Token::Some,
142 Token::Struct {
143 name: "PartialMember",
144 len: 8,
145 },
146 Token::Str("communication_disabled_until"),
147 Token::None,
148 Token::Str("deaf"),
149 Token::Bool(false),
150 Token::Str("flags"),
151 Token::U64(flags.bits()),
152 Token::Str("joined_at"),
153 Token::Some,
154 Token::Str("2015-04-26T06:26:56.936000+00:00"),
155 Token::Str("mute"),
156 Token::Bool(true),
157 Token::Str("nick"),
158 Token::Some,
159 Token::Str("bar"),
160 Token::Str("roles"),
161 Token::Seq { len: Some(0) },
162 Token::SeqEnd,
163 Token::Str("user"),
164 Token::None,
165 Token::StructEnd,
166 Token::Str("username"),
167 Token::Str("foo"),
168 Token::Str("public_flags"),
169 Token::U64(0),
170 Token::StructEnd,
171 ],
172 );
173 Ok(())
174 }
175}