pub mod events;
pub mod state;
use crate::{user::User, Error};
use serde::Deserialize;
#[cfg(test)]
use serde::Serialize;
#[derive(Copy, Clone, Debug, PartialEq, Eq, serde_repr::Deserialize_repr)]
#[cfg_attr(test, derive(serde_repr::Serialize_repr))]
#[repr(u8)]
pub enum RelationKind {
None = 0,
Friend = 1,
Blocked = 2,
PendingIncoming = 3,
PendingOutgoing = 4,
Implicit = 5,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
#[serde(rename_all = "snake_case")]
pub enum RelationStatus {
Offline,
Online,
Idle,
#[serde(rename = "dnd")]
DoNotDisturb,
}
#[derive(Default, Clone, Debug, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct RelationshipActivityTimestamps {
#[serde(
skip_serializing_if = "Option::is_none",
with = "crate::util::datetime_opt",
default
)]
pub start: Option<time::OffsetDateTime>,
#[serde(
skip_serializing_if = "Option::is_none",
with = "crate::util::datetime_opt",
default
)]
pub end: Option<time::OffsetDateTime>,
}
use crate::activity;
#[derive(Default, Clone, Debug, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct RelationshipActivity {
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
#[serde(skip_serializing, with = "crate::util::datetime_opt")]
pub created_at: Option<time::OffsetDateTime>,
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub details: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamps: Option<RelationshipActivityTimestamps>,
#[serde(skip_serializing_if = "Option::is_none")]
pub assets: Option<activity::Assets>,
#[serde(skip_serializing_if = "Option::is_none")]
pub party: Option<activity::Party>,
#[serde(skip_serializing_if = "Option::is_none")]
pub secrets: Option<activity::Secrets>,
#[serde(rename = "type")]
pub kind: activity::ActivityKind,
#[serde(default)]
pub instance: bool,
}
#[derive(Debug, Clone, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct RelationshipPresence {
pub status: RelationStatus,
pub activity: Option<RelationshipActivity>,
}
#[derive(Debug, Clone, Deserialize)]
#[cfg_attr(test, derive(Serialize))]
pub struct Relationship {
#[serde(rename = "type")]
pub kind: RelationKind,
pub user: User,
pub presence: RelationshipPresence,
}
impl crate::Discord {
pub async fn get_relationships(&self) -> Result<Vec<Relationship>, Error> {
let rx = self.send_rpc(crate::proto::CommandKind::GetRelationships, ())?;
handle_response!(rx, crate::proto::Command::GetRelationships { relationships } => {
Ok(relationships)
})
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{activity, proto::event};
#[test]
fn deserializes() {
let event = r#"{"cmd":"DISPATCH","data":{"type":1,"user":{"id":"682969165652689005","username":"jake.shadle","discriminator":"7557","avatar":"15bbd75c8ee6610d045852e7ea998a35","bot":false,"flags":0,"premium_type":0},"presence":{"status":"online","activity":{"created_at":"1632819046295","id":"e92ece5eb4ce629","name":"Ark [dev debug]","timestamps":{"start":"1632819046199"},"type":0}}},"evt":"RELATIONSHIP_UPDATE","nonce":null}"#;
let update: crate::proto::event::EventFrame =
serde_json::from_str(event).expect("failed to deserialize");
insta::assert_json_snapshot!(update);
}
#[test]
fn serde() {
let eve = event::EventFrame {
inner: event::Event::RelationshipUpdate(std::sync::Arc::new(Relationship {
kind: RelationKind::Friend,
user: User {
id: crate::types::Snowflake(123414231424),
username: "name".to_owned(),
discriminator: Some(52),
avatar: Some(crate::user::Avatar([
0xf6, 0x2f, 0x2a, 0x75, 0x5c, 0xb1, 0x8c, 0x94, 0xdc, 0x5c, 0xda, 0x94,
0x44, 0x10, 0x24, 0xf1,
])),
is_bot: false,
},
presence: RelationshipPresence {
status: RelationStatus::DoNotDisturb,
activity: Some(RelationshipActivity {
session_id: Some("6bb1ddaea510750e905615286709d632".to_owned()),
created_at: Some(crate::util::timestamp(1628629162447)),
assets: Some(activity::Assets {
large_image: Some(
"spotify:ab67616d0000b273d1e326d10706f3d8562d77f8".to_owned(),
),
large_text: Some("To the Moon".to_owned()),
small_image: None,
small_text: None,
}),
details: Some("To the Moon".to_owned()),
instance: false,
kind: activity::ActivityKind::Listening,
party: Some(activity::Party {
id: "spotify: 216453179196440576".to_owned(),
size: None,
privacy: None,
}),
secrets: None,
state: Some("Rob Curly".to_owned()),
timestamps: Some(RelationshipActivityTimestamps {
start: Some(crate::util::timestamp(1628629161811)),
end: Some(crate::util::timestamp(1628629327961)),
}),
}),
},
})),
};
insta::assert_json_snapshot!(eve);
}
}