twilight_model/channel/message/
reaction.rs1use crate::{
2 id::{marker::EmojiMarker, Id},
3 util::HexColor,
4};
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
9pub struct Reaction {
10 pub burst_colors: Vec<HexColor>,
12 pub count: u64,
14 pub count_details: ReactionCountDetails,
16 pub emoji: EmojiReactionType,
18 pub me: bool,
20 pub me_burst: bool,
22}
23
24#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
26#[serde(untagged)]
27pub enum EmojiReactionType {
28 Custom {
32 #[serde(default)]
34 animated: bool,
35 id: Id<EmojiMarker>,
41 name: Option<String>,
45 },
46 Unicode {
53 name: String,
55 },
56}
57
58#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
60pub struct ReactionCountDetails {
61 pub burst: u64,
63 pub normal: u64,
65}
66
67#[cfg(test)]
68mod tests {
69 use super::{EmojiReactionType, Reaction, ReactionCountDetails};
70 use crate::{id::Id, util::HexColor};
71 use serde_test::Token;
72
73 #[test]
74 fn message_reaction_unicode() {
75 let value = Reaction {
76 burst_colors: Vec::from([HexColor(255, 255, 255)]),
77 count: 7,
78 count_details: ReactionCountDetails {
79 burst: 0,
80 normal: 7,
81 },
82 emoji: EmojiReactionType::Unicode {
83 name: "a".to_owned(),
84 },
85 me: true,
86 me_burst: false,
87 };
88
89 serde_test::assert_tokens(
90 &value,
91 &[
92 Token::Struct {
93 name: "Reaction",
94 len: 6,
95 },
96 Token::Str("burst_colors"),
97 Token::Seq { len: Some(1) },
98 Token::Str("#FFFFFF"),
99 Token::SeqEnd,
100 Token::Str("count"),
101 Token::U64(7),
102 Token::Str("count_details"),
103 Token::Struct {
104 name: "ReactionCountDetails",
105 len: 2,
106 },
107 Token::Str("burst"),
108 Token::U64(0),
109 Token::Str("normal"),
110 Token::U64(7),
111 Token::StructEnd,
112 Token::Str("emoji"),
113 Token::Struct {
114 name: "EmojiReactionType",
115 len: 1,
116 },
117 Token::Str("name"),
118 Token::Str("a"),
119 Token::StructEnd,
120 Token::Str("me"),
121 Token::Bool(true),
122 Token::Str("me_burst"),
123 Token::Bool(false),
124 Token::StructEnd,
125 ],
126 );
127 }
128
129 #[test]
130 fn custom() {
131 let value = EmojiReactionType::Custom {
132 animated: false,
133 id: Id::new(1337),
134 name: Some("foo".to_owned()),
135 };
136
137 serde_test::assert_tokens(
138 &value,
139 &[
140 Token::Struct {
141 name: "EmojiReactionType",
142 len: 3,
143 },
144 Token::Str("animated"),
145 Token::Bool(false),
146 Token::Str("id"),
147 Token::NewtypeStruct { name: "Id" },
148 Token::Str("1337"),
149 Token::Str("name"),
150 Token::Some,
151 Token::Str("foo"),
152 Token::StructEnd,
153 ],
154 );
155
156 serde_test::assert_de_tokens(
159 &value,
160 &[
161 Token::Struct {
162 name: "ReactionType",
163 len: 2,
164 },
165 Token::Str("id"),
166 Token::NewtypeStruct { name: "Id" },
167 Token::Str("1337"),
168 Token::Str("name"),
169 Token::Some,
170 Token::Str("foo"),
171 Token::StructEnd,
172 ],
173 );
174 }
175
176 #[test]
177 fn unicode() {
178 let value = EmojiReactionType::Unicode {
179 name: "\u{1f643}".to_owned(),
180 };
181
182 serde_test::assert_tokens(
183 &value,
184 &[
185 Token::Struct {
186 name: "EmojiReactionType",
187 len: 1,
188 },
189 Token::Str("name"),
190 Token::Str("\u{1f643}"),
191 Token::StructEnd,
192 ],
193 );
194 }
195}