sponsor_block/client/user/
user_info.rs

1// Uses
2use serde::Deserialize;
3use serde_json::from_str as from_json_str;
4
5use crate::{
6	error::Result,
7	util::get_response_text,
8	Client,
9	LocalUserIdSlice,
10	PublicUserId,
11	PublicUserIdSlice,
12	SegmentUuid,
13};
14
15/// The results of a user info request.
16#[derive(Deserialize, Debug, Default)]
17#[serde(default, rename_all = "camelCase")]
18pub struct UserInfo {
19	/// The user's public user ID.
20	#[serde(rename = "userID")]
21	pub public_user_id: PublicUserId,
22	/// The user's username.
23	pub user_name: Option<String>,
24	/// The number of minutes this user has saved other users.
25	pub minutes_saved: f32,
26	/// The total number of segments submitted, excluding ignored & hidden
27	/// segments.
28	pub segment_count: u32,
29	/// The total number of ignored & hidden segments submitted.
30	pub ignored_segment_count: u32,
31	/// The total number of views, excluding those on ignored & hidden segments
32	/// that other users have on this user's segments.
33	pub view_count: u32,
34	/// The total number of views on ignored & hidden segments that other users
35	/// have on this user's segments.
36	pub ignored_view_count: u32,
37	/// The number of currently-enabled warnings.
38	pub warnings: u32,
39	/// The user's reputation.
40	pub reputation: f32,
41	/// The VIP status.
42	pub vip: bool,
43	/// the UUID of the last submitted segment.
44	#[serde(rename = "lastSegmentID")]
45	pub last_segment_id: Option<SegmentUuid>,
46}
47
48impl UserInfo {
49	/// A convenience function that gets the total segment count.
50	/// (`segment_count + ignored_segment_count`)
51	#[must_use]
52	pub fn total_segment_count(&self) -> u32 {
53		self.segment_count + self.ignored_segment_count
54	}
55
56	/// A convenience function that gets the total view count.
57	/// (`view_count + ignored_view_count`)
58	#[must_use]
59	pub fn total_view_count(&self) -> u32 {
60		self.view_count + self.ignored_view_count
61	}
62}
63
64// Function Constants
65const API_ENDPOINT: &str = "/userInfo";
66
67// Function Implementation
68impl Client {
69	/// Fetches a user's info using a public user ID.
70	///
71	/// # Errors
72	/// Can return pretty much any error type from [`SponsorBlockError`]. See
73	/// the error type definitions for explanations of when they might be
74	/// encountered.
75	///
76	/// [`SponsorBlockError`]: crate::SponsorBlockError
77	pub async fn fetch_user_info_public(
78		&self,
79		public_user_id: &PublicUserIdSlice,
80	) -> Result<UserInfo> {
81		// Build the request
82		let request = self
83			.http
84			.get(format!("{}{}", &self.base_url, API_ENDPOINT))
85			.query(&[("publicUserID", public_user_id)]);
86
87		// Send the request
88		let response = get_response_text(request.send().await?).await?;
89
90		// Parse the response
91		let mut result = from_json_str::<UserInfo>(response.as_str())?;
92		// The user name is set to the public user ID if not set. This converts it to a
93		// more idiomatic value transparently.
94		if result
95			.user_name
96			.as_ref()
97			.expect("userName field was not set")
98			.eq(&result.public_user_id)
99		{
100			result.user_name = None;
101		}
102		Ok(result)
103	}
104
105	/// Fetches a user's info using a local (private) user ID.
106	///
107	/// # Errors
108	/// Can return pretty much any error type from [`SponsorBlockError`]. See
109	/// the error type definitions for explanations of when they might be
110	/// encountered.
111	///
112	/// [`SponsorBlockError`]: crate::SponsorBlockError
113	pub async fn fetch_user_info_local(
114		&self,
115		local_user_id: &LocalUserIdSlice,
116	) -> Result<UserInfo> {
117		// Build the request
118		let request = self
119			.http
120			.get(format!("{}{}", &self.base_url, API_ENDPOINT))
121			.query(&[("userID", local_user_id)]);
122
123		// Send the request
124		let response = get_response_text(request.send().await?).await?;
125
126		// Parse the response
127		let mut result = from_json_str::<UserInfo>(response.as_str())?;
128		// The user name is set to the public user ID if not set. This converts it to a
129		// more idiomatic value transparently.
130		if result
131			.user_name
132			.as_ref()
133			.expect("userName field was not set")
134			.eq(&result.public_user_id)
135		{
136			result.user_name = None;
137		}
138		Ok(result)
139	}
140}