Skip to main content

mlb_api/requests/team/
stats.rs

1#![allow(clippy::trait_duplication_in_bounds, reason = "serde")]
2
3use crate::game_types::GameType;
4use crate::person::PersonId;
5use crate::request::RequestURL;
6use crate::season::SeasonId;
7use crate::sport::SportId;
8use crate::stat_groups::StatGroup;
9use crate::stat_types::StatType;
10use crate::stats::Stats;
11use crate::team::TeamId;
12use crate::types::{Copyright, MLB_API_DATE_FORMAT};
13use bon::Builder;
14use chrono::NaiveDate;
15use either::Either;
16use itertools::Itertools;
17use serde::Deserialize;
18use std::fmt::{Display, Formatter};
19use std::marker::PhantomData;
20
21#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
22#[serde(bound = "S: Stats")]
23pub struct TeamsStatsResponse<S: Stats> {
24	pub copyright: Copyright,
25	pub stats: S,
26}
27
28#[derive(Builder)]
29#[builder(derive(Into))]
30#[builder(start_fn(vis = ""))]
31pub struct TeamsStatsRequest<S: Stats> {
32	#[builder(setters(vis = "", name = __id_internal))]
33	pub id: Either<TeamId, SportId>,
34	#[builder(into)]
35	pub season: Option<SeasonId>,
36	pub game_type: GameType,
37	pub stat_types: Vec<StatType>,
38	pub stat_groups: Vec<StatGroup>,
39	pub start_date: Option<NaiveDate>,
40	pub end_date: Option<NaiveDate>,
41	#[builder(into)]
42	pub opposing_player: Option<PersonId>,
43	#[builder(into)]
44	pub opposing_team: Option<PersonId>,
45	#[builder(skip)]
46	_marker: PhantomData<S>,
47}
48
49impl<S: Stats, State: teams_stats_request_builder::State + teams_stats_request_builder::IsComplete> crate::request::RequestURLBuilderExt for TeamsStatsRequestBuilder<S, State> {
50    type Built = TeamsStatsRequest<S>;
51}
52
53impl<S: Stats> TeamsStatsRequest<S> {
54	pub fn for_team(team_id: impl Into<TeamId>) -> TeamsStatsRequestBuilder<S, teams_stats_request_builder::SetId> {
55		Self::builder().__id_internal(Either::Left(team_id.into()))
56	}
57
58	pub fn for_sport(sport_id: impl Into<SportId>) -> TeamsStatsRequestBuilder<S, teams_stats_request_builder::SetId> {
59		Self::builder().__id_internal(Either::Right(sport_id.into()))
60	}
61}
62
63impl<S: Stats> Display for TeamsStatsRequest<S> {
64	#[allow(clippy::cognitive_complexity, reason = "still readable")]
65	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
66		match self.id {
67			Either::Left(id) => write!(
68				f,
69				"http://statsapi.mlb.com/api/v1/teams/{id}/stats{params}",
70				params = gen_params! {
71					"season"?: self.season,
72					"gameType": self.game_type,
73					"stats": self.stat_types.iter().join(","),
74					"group": self.stat_groups.iter().join(","),
75					"startDate"?: self.start_date.map(|x| x.format(MLB_API_DATE_FORMAT)),
76					"endDate"?: self.start_date.map(|x| x.format(MLB_API_DATE_FORMAT)),
77					"opposingPlayerId"?: self.opposing_player,
78					"opposingTeamId"?: self.opposing_team,
79				}
80			),
81			Either::Right(id) => write!(
82				f,
83				"http://statsapi.mlb.com/api/v1/teams/stats{params}",
84				params = gen_params! {
85					"season"?: self.season,
86					"gameType": self.game_type,
87					"stats": self.stat_types.iter().join(","),
88					"group": self.stat_groups.iter().join(","),
89					"sportId": id,
90					"startDate"?: self.start_date.map(|x| x.format(MLB_API_DATE_FORMAT)),
91					"endDate"?: self.start_date.map(|x| x.format(MLB_API_DATE_FORMAT)),
92					"opposingPlayerId"?: self.opposing_player,
93					"opposingTeamId"?: self.opposing_team,
94				}
95			),
96		}
97	}
98}
99
100impl<S: Stats> RequestURL for TeamsStatsRequest<S> {
101	type Response = TeamsStatsResponse<S>;
102}