Skip to main content

mlb_api/requests/team/
leaders.rs

1use crate::season::SeasonId;
2use crate::stats::leaders::StatLeaders;
3use crate::team::TeamId;
4use crate::types::{Copyright, PlayerPool};
5use bon::Builder;
6use itertools::Itertools;
7use serde::Deserialize;
8use std::fmt::{Display, Formatter};
9use crate::baseball_stats::BaseballStatId;
10use crate::game_types::GameType;
11use crate::request::RequestURL;
12
13#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
14#[serde(rename_all = "camelCase")]
15pub struct TeamStatLeadersResponse {
16	pub copyright: Copyright,
17	pub team_leaders: Vec<StatLeaders>,
18}
19
20/// Stat leaders per team
21#[derive(Builder)]
22#[builder(derive(Into))]
23pub struct TeamStatLeadersRequest {
24	#[builder(into)]
25	pub team_id: TeamId,
26	pub stats: Vec<BaseballStatId>,
27	#[builder(into)]
28	pub season: Option<SeasonId>,
29	#[builder(default)]
30	pub pool: PlayerPool,
31
32	/// [`None`] represents matching for all [`GameType`]s.
33	pub game_types: Option<Vec<GameType>>,
34}
35
36impl<S: team_stat_leaders_request_builder::State + team_stat_leaders_request_builder::IsComplete> crate::request::RequestURLBuilderExt for TeamStatLeadersRequestBuilder<S> {
37	type Built = TeamStatLeadersRequest;
38}
39
40impl Display for TeamStatLeadersRequest {
41	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42		write!(
43			f,
44			"http://statsapi.mlb.com/api/v1/teams/{}/leaders{params}",
45			self.team_id,
46			params = gen_params! {
47				"leaderCategories": self.stats.iter().join(","),
48				"season"?: self.season,
49				"pool": self.pool,
50				"game_types"?: self.game_types.as_ref().map(|x| x.iter().join(",")),
51			}
52		)
53	}
54}
55
56impl RequestURL for TeamStatLeadersRequest {
57	type Response = TeamStatLeadersResponse;
58}
59
60#[cfg(test)]
61mod tests {
62	use crate::baseball_stats::BaseballStat;
63	use crate::meta::MetaRequest;
64	use crate::request::{RequestURL, RequestURLBuilderExt};
65	use crate::team::leaders::TeamStatLeadersRequest;
66	use crate::team::teams::TeamsRequest;
67
68	#[tokio::test]
69	async fn test_all_mlb_teams_all_stats() {
70		let all_stats = MetaRequest::<BaseballStat>::new().get().await.unwrap().entries.into_iter().map(|stat| stat.id.clone()).collect::<Vec<_>>();
71
72		for team in TeamsRequest::mlb_teams().build_and_get().await.unwrap().teams {
73			let request = TeamStatLeadersRequest::builder().team_id(team.id).stats(all_stats.clone()).build();
74			let _all_stats = request.get()
75			.await
76			.unwrap_or_else(|_| panic!("expected team #{} to be valid; {request}", team.id));
77		}
78	}
79}