1use std::fmt::{Display, Formatter, Result as FmtResult};
3
4use serde_json::Error as JsonError;
5use serde_repr::{Deserialize_repr, Serialize_repr};
6
7use crate::gateway::{Opcodes, SendablePacket, SendPacket};
8use crate::Snowflake;
9
10#[derive(Deserialize, Serialize, Debug, Clone, Default)]
12pub struct Activity {
13 pub name: String,
15 #[serde(rename = "type")]
17 pub kind: ActivityType,
18 #[serde(default)]
20 pub url: String,
21 #[serde(default)]
23 pub timestamps: Option<ActivityTimestamps>,
24 pub application_id: Option<Snowflake>,
26 pub details: Option<String>,
28 pub state: Option<String>,
30 #[serde(default)]
32 pub party: Option<ActivityParty>,
33 #[serde(default)]
35 pub assets: Option<ActivityAssets>,
36 #[serde(default)]
38 pub secrets: Option<ActivitySecrets>,
39 #[serde(default)]
41 pub instance: Option<bool>,
42 #[serde(default)]
44 pub flags: Option<i32>
45}
46
47#[derive(Deserialize, Serialize, Debug, Clone, Default)]
49pub struct ClientActivity {
50 pub name: String,
52 #[serde(rename = "type")]
54 pub kind: ActivityType,
55 pub url: Option<String>,
57}
58
59impl ClientActivity {
60 pub fn game(name: &str) -> Self {
62 Self {
63 name: name.to_string(),
64 kind: ActivityType::Game,
65 url: None
66 }
67 }
68
69 pub fn streaming(name: &str, url: &str) -> Self {
71 Self {
72 name: name.to_string(),
73 kind: ActivityType::Streaming,
74 url: Some(url.to_string())
75 }
76 }
77
78 pub fn listening(name: &str) -> Self {
80 Self {
81 name: name.to_string(),
82 kind: ActivityType::Listening,
83 url: None
84 }
85 }
86}
87
88#[derive(Deserialize, Serialize, Debug, Clone)]
90pub struct Presence {
91 pub user: PresenceUser,
93 #[serde(default)]
95 pub roles: Option<Vec<Snowflake>>,
96 #[serde(default)]
98 pub game: Option<Activity>,
99 #[serde(default)]
101 pub guild_id: Option<Snowflake>,
102 #[serde(default)]
104 pub status: Option<Status>,
105 #[serde(default)]
106 pub activities: Option<Vec<Activity>>,
108 #[serde(default)]
110 pub client_status: Option<ClientStatus>
111
112}
113
114#[derive(Deserialize, Serialize, Debug, Clone, Default)]
116pub struct PresenceUser {
117 pub id: Snowflake
119}
120
121#[derive(Deserialize, Serialize, Debug, Clone, Default)]
123pub struct ClientPresence {
124 pub since: Option<i32>,
126 pub game: Option<ClientActivity>,
128 pub status: String,
130 pub afk: bool
132}
133
134#[derive(Deserialize, Serialize, Debug, Clone, Default)]
136pub struct ClientStatus {
137 #[serde(default)]
139 pub desktop: Option<String>,
140 #[serde(default)]
142 pub mobile: Option<String>,
143 #[serde(default)]
145 pub web: Option<String>
146}
147
148#[derive(Deserialize, Serialize, Debug, Clone, Default)]
150pub struct ActivityTimestamps {
151 #[serde(default)]
153 pub start: Option<u64>,
154 #[serde(default)]
156 pub end: Option<u64>
157}
158
159#[derive(Deserialize, Serialize, Debug, Clone, Default)]
161pub struct ActivityParty {
162 #[serde(default)]
164 pub id: String,
165 #[serde(default)]
167 pub size: [i32; 2]
168}
169
170#[derive(Deserialize, Serialize, Debug, Clone, Default)]
172pub struct ActivityAssets {
173 #[serde(default)]
175 pub large_image: String,
176 #[serde(default)]
178 pub large_text: String,
179 #[serde(default)]
181 pub small_image: String,
182 #[serde(default)]
184 pub small_text: String
185}
186
187#[derive(Deserialize, Serialize, Debug, Clone, Default)]
189pub struct ActivitySecrets {
190 #[serde(default)]
192 pub join: String,
193 #[serde(default)]
195 pub spectate: String,
196 #[serde(rename = "match", default)]
198 pub match_type: String
199}
200
201
202impl SendablePacket for ClientPresence {
203 fn to_json(self) -> Result<String, JsonError> {
204 serde_json::to_string(&SendPacket {
205 op: Opcodes::StatusUpdate,
206 d: self
207 })
208 }
209
210 fn bytes(self) -> Result<Vec<u8>, JsonError> {
211 let json = self.to_json()?;
212
213 Ok(json.as_bytes().to_vec())
214 }
215}
216#[derive(Deserialize_repr, Serialize_repr, Debug, Clone)]
218#[repr(u8)]
219pub enum ActivityType {
220 Game,
221 Streaming,
222 Listening,
223 Watching
224}
225
226impl Default for ActivityType {
227 fn default() -> Self {
228 ActivityType::Game
229 }
230}
231#[derive(Deserialize, Serialize, Debug, Clone)]
233pub enum Status {
234 #[serde(rename = "online")]
235 Online,
236 #[serde(rename = "dnd")]
237 DnD,
238 #[serde(rename = "idle")]
239 Idle,
240 #[serde(rename = "invisible")]
241 Invisible,
242 #[serde(rename = "offline")]
243 Offline
244}
245
246impl Default for Status {
247 fn default() -> Self {
248 Status::Online
249 }
250}
251
252
253impl Display for Status {
254 fn fmt(&self, f: &mut Formatter) -> FmtResult {
255 match self {
256 Status::Online => write!(f, "online"),
257 Status::DnD => write!(f, "dnd"),
258 Status::Idle => write!(f, "idle"),
259 Status::Invisible => write!(f, "invisible"),
260 Status::Offline => write!(f, "offline")
261 }
262 }
263}