use std::fmt::{Display, Formatter, Result as FmtResult};
use serde_json::Error as JsonError;
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::gateway::{Opcodes, SendablePacket, SendPacket};
use crate::Snowflake;
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct Activity {
pub name: String,
#[serde(rename = "type")]
pub kind: ActivityType,
#[serde(default)]
pub url: String,
#[serde(default)]
pub timestamps: Option<ActivityTimestamps>,
pub application_id: Option<Snowflake>,
pub details: Option<String>,
pub state: Option<String>,
#[serde(default)]
pub party: Option<ActivityParty>,
#[serde(default)]
pub assets: Option<ActivityAssets>,
#[serde(default)]
pub secrets: Option<ActivitySecrets>,
#[serde(default)]
pub instance: Option<bool>,
#[serde(default)]
pub flags: Option<i32>
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct ClientActivity {
pub name: String,
#[serde(rename = "type")]
pub kind: ActivityType,
pub url: Option<String>,
}
impl ClientActivity {
pub fn game(name: &str) -> Self {
Self {
name: name.to_string(),
kind: ActivityType::Game,
url: None
}
}
pub fn streaming(name: &str, url: &str) -> Self {
Self {
name: name.to_string(),
kind: ActivityType::Streaming,
url: Some(url.to_string())
}
}
pub fn listening(name: &str) -> Self {
Self {
name: name.to_string(),
kind: ActivityType::Listening,
url: None
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Presence {
pub user: PresenceUser,
#[serde(default)]
pub roles: Option<Vec<Snowflake>>,
#[serde(default)]
pub game: Option<Activity>,
#[serde(default)]
pub guild_id: Option<Snowflake>,
#[serde(default)]
pub status: Option<Status>,
#[serde(default)]
pub activities: Option<Vec<Activity>>,
#[serde(default)]
pub client_status: Option<ClientStatus>
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct PresenceUser {
pub id: Snowflake
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct ClientPresence {
pub since: Option<i32>,
pub game: Option<ClientActivity>,
pub status: String,
pub afk: bool
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct ClientStatus {
#[serde(default)]
pub desktop: Option<String>,
#[serde(default)]
pub mobile: Option<String>,
#[serde(default)]
pub web: Option<String>
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct ActivityTimestamps {
#[serde(default)]
pub start: Option<u64>,
#[serde(default)]
pub end: Option<u64>
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct ActivityParty {
#[serde(default)]
pub id: String,
#[serde(default)]
pub size: [i32; 2]
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct ActivityAssets {
#[serde(default)]
pub large_image: String,
#[serde(default)]
pub large_text: String,
#[serde(default)]
pub small_image: String,
#[serde(default)]
pub small_text: String
}
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
pub struct ActivitySecrets {
#[serde(default)]
pub join: String,
#[serde(default)]
pub spectate: String,
#[serde(rename = "match", default)]
pub match_type: String
}
impl SendablePacket for ClientPresence {
fn to_json(self) -> Result<String, JsonError> {
serde_json::to_string(&SendPacket {
op: Opcodes::StatusUpdate,
d: self
})
}
}
#[derive(Deserialize_repr, Serialize_repr, Debug, Clone)]
#[repr(u8)]
pub enum ActivityType {
Game,
Streaming,
Listening
}
impl Default for ActivityType {
fn default() -> Self {
ActivityType::Game
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub enum Status {
#[serde(rename = "online")]
Online,
#[serde(rename = "dnd")]
DnD,
#[serde(rename = "idle")]
Idle,
#[serde(rename = "invisible")]
Invisible,
#[serde(rename = "offline")]
Offline
}
impl Display for Status {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
match self {
Status::Online => write!(f, "online"),
Status::DnD => write!(f, "dnd"),
Status::Idle => write!(f, "idle"),
Status::Invisible => write!(f, "invisible"),
Status::Offline => write!(f, "offline")
}
}
}