plex_api/myplex/sharing/
friend.rs1use crate::{
2 isahc_compat::StatusCodeExt, myplex::account::RestrictionProfile, url::MYPLEX_INVITES_FRIENDS,
3 Error, HttpClient, Result,
4};
5use http::StatusCode;
6use isahc::AsyncReadResponseExt;
7use serde::{Deserialize, Serialize};
8use serde_plain::derive_display_from_serialize;
9use time::OffsetDateTime;
10
11#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
12#[serde(rename_all = "snake_case")]
13pub enum InviteStatus {
14 PendingSent,
15 Accepted,
16 PendingReceived,
17 Pending,
18 #[cfg(not(feature = "tests_deny_unknown_fields"))]
19 #[serde(other)]
20 Unknown,
21}
22
23derive_display_from_serialize!(InviteStatus);
24
25#[derive(Serialize, Deserialize, Debug, Clone)]
26#[serde(rename_all = "camelCase")]
27#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
28pub struct Friend {
29 pub id: u64,
31 pub uuid: String,
33 pub title: String,
36 pub username: Option<String>,
38 pub email: Option<String>,
40 pub restricted: bool,
42 pub restriction_profile: Option<RestrictionProfile>,
44 pub friendly_name: Option<String>,
46 #[serde(default, with = "time::serde::rfc3339::option")]
47 pub friendship_created_at: Option<OffsetDateTime>,
48 #[serde(with = "http_serde::uri")]
50 pub thumb: http::Uri,
51 pub home: bool,
53 pub status: Option<InviteStatus>,
55 pub sharing_settings: Option<super::server::Settings>,
57 #[serde(default)]
59 pub shared_servers: Vec<super::server::SharedServer>,
60 #[serde(default)]
62 pub shared_sources: Vec<String>,
63 #[serde(skip)]
64 pub(crate) client: Option<HttpClient>,
65}
66
67impl Friend {
68 #[tracing::instrument(level = "debug", skip(self))]
70 pub async fn accept(self) -> Result<Friend> {
71 if !matches!(
72 self.status,
73 Some(InviteStatus::PendingReceived) | Some(InviteStatus::Pending)
74 ) {
75 return Err(Error::InviteAcceptingNotPendingReceived);
76 }
77
78 let mut friend: Friend = self
79 .client()
80 .post(format!("{}/{}/accept", MYPLEX_INVITES_FRIENDS, self.id))
81 .json()
82 .await?;
83 friend.client.clone_from(&self.client);
84 Ok(friend)
85 }
86
87 fn client(&self) -> &HttpClient {
90 self.client.as_ref().unwrap()
91 }
92
93 #[tracing::instrument(level = "debug", skip(self))]
95 pub async fn delete(self) -> Result<()> {
96 let mut response = self
97 .client()
98 .delete(format!("{}/{}", MYPLEX_INVITES_FRIENDS, self.id))
99 .send()
100 .await?;
101
102 match response.status().as_http_status() {
103 StatusCode::OK | StatusCode::NO_CONTENT => {
104 response.consume().await?;
105 Ok(())
106 }
107 _ => Err(Error::from_response(response).await),
108 }
109 }
110}