twilight_model/guild/widget/
mod.rs1mod settings;
2
3pub use self::settings::GuildWidgetSettings;
4
5use crate::{
6 gateway::presence::Status,
7 id::{
8 marker::{ChannelMarker, GuildMarker, UserMarker},
9 AnonymizableId, Id,
10 },
11 user::{discriminator, DiscriminatorDisplay},
12 util::ImageHash,
13};
14use serde::{Deserialize, Serialize};
15
16#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
17pub struct GuildWidget {
18 pub channels: Vec<GuildWidgetChannel>,
19 pub id: Id<GuildMarker>,
20 pub instant_invite: Option<String>,
21 pub members: Vec<GuildWidgetMember>,
22 pub name: String,
23 pub presence_count: u64,
24}
25
26#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
27pub struct GuildWidgetChannel {
28 pub id: Id<ChannelMarker>,
29 pub name: String,
30 pub position: i64,
31}
32
33#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
34pub struct GuildWidgetMember {
35 pub avatar: Option<ImageHash>,
36 pub avatar_url: Option<String>,
37 #[serde(with = "discriminator")]
38 pub discriminator: u16,
39 pub id: AnonymizableId<UserMarker>,
41 #[serde(rename = "username")]
42 pub name: String,
43 pub status: Status,
44}
45
46impl GuildWidgetMember {
47 pub const fn discriminator(&self) -> DiscriminatorDisplay {
51 DiscriminatorDisplay::new(self.discriminator)
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::{GuildWidget, GuildWidgetChannel, GuildWidgetMember, Id, Status};
58 use crate::id::AnonymizableId;
59 use serde::{Deserialize, Serialize};
60 use serde_test::Token;
61 use static_assertions::{assert_fields, assert_impl_all};
62 use std::{fmt::Debug, hash::Hash};
63
64 assert_fields!(
65 GuildWidget: channels,
66 id,
67 instant_invite,
68 members,
69 name,
70 presence_count
71 );
72 assert_fields!(GuildWidgetChannel: id, name, position);
73 assert_fields!(
74 GuildWidgetMember: avatar,
75 avatar_url,
76 discriminator,
77 id,
78 name,
79 status
80 );
81 assert_impl_all!(
82 GuildWidget: Clone,
83 Debug,
84 Deserialize<'static>,
85 Eq,
86 Hash,
87 PartialEq,
88 Serialize,
89 Send,
90 Sync
91 );
92 assert_impl_all!(
93 GuildWidgetChannel: Clone,
94 Debug,
95 Deserialize<'static>,
96 Eq,
97 Hash,
98 PartialEq,
99 Serialize,
100 Send,
101 Sync
102 );
103 assert_impl_all!(
104 GuildWidgetMember: Clone,
105 Debug,
106 Deserialize<'static>,
107 Eq,
108 Hash,
109 PartialEq,
110 Serialize,
111 Send,
112 Sync
113 );
114
115 #[test]
116 fn guild_widget() {
117 let value = GuildWidget {
118 channels: Vec::from([GuildWidgetChannel {
119 id: Id::new(2),
120 name: "General".to_string(),
121 position: 1,
122 }]),
123 id: Id::new(1),
124 instant_invite: Some("https://discord.com/invite/P8PkgN2".to_string()),
125 members: Vec::from([GuildWidgetMember {
126 avatar: None,
127 avatar_url: Some("widget avatar link".to_string()),
128 discriminator: 1,
129 id: AnonymizableId::Anonymized,
130 name: "Foo".to_string(),
131 status: Status::Online,
132 }]),
133 name: "Twilight".to_string(),
134 presence_count: 15,
135 };
136
137 serde_test::assert_tokens(
138 &value,
139 &[
140 Token::Struct {
141 name: "GuildWidget",
142 len: 6,
143 },
144 Token::Str("channels"),
145 Token::Seq { len: Some(1) },
146 Token::Struct {
147 name: "GuildWidgetChannel",
148 len: 3,
149 },
150 Token::Str("id"),
151 Token::NewtypeStruct { name: "Id" },
152 Token::Str("2"),
153 Token::Str("name"),
154 Token::Str("General"),
155 Token::Str("position"),
156 Token::I64(1),
157 Token::StructEnd,
158 Token::SeqEnd,
159 Token::Str("id"),
160 Token::NewtypeStruct { name: "Id" },
161 Token::Str("1"),
162 Token::Str("instant_invite"),
163 Token::Some,
164 Token::Str("https://discord.com/invite/P8PkgN2"),
165 Token::Str("members"),
166 Token::Seq { len: Some(1) },
167 Token::Struct {
168 name: "GuildWidgetMember",
169 len: 6,
170 },
171 Token::Str("avatar"),
172 Token::None,
173 Token::Str("avatar_url"),
174 Token::Some,
175 Token::Str("widget avatar link"),
176 Token::Str("discriminator"),
177 Token::Str("0001"),
178 Token::Str("id"),
179 Token::NewtypeStruct {
180 name: "AnonymizableId",
181 },
182 Token::Str("0"),
183 Token::Str("username"),
184 Token::Str("Foo"),
185 Token::Str("status"),
186 Token::UnitVariant {
187 name: "Status",
188 variant: "online",
189 },
190 Token::StructEnd,
191 Token::SeqEnd,
192 Token::Str("name"),
193 Token::Str("Twilight"),
194 Token::Str("presence_count"),
195 Token::U64(15),
196 Token::StructEnd,
197 ],
198 );
199 }
200}