mlb_api/requests/schedule/postseason/
series.rs1use crate::Copyright;
2use crate::meta::GameType;
3use crate::request::RequestURL;
4use crate::schedule::{ScheduleGame, ScheduleHydrations};
5use crate::season::SeasonId;
6use crate::sport::SportId;
7use crate::team::TeamId;
8use bon::Builder;
9use itertools::Itertools;
10use serde::de::Error;
11use serde::{Deserialize, Deserializer};
12use std::fmt::{Display, Formatter};
13use std::marker::PhantomData;
14
15#[derive(Debug, Deserialize, PartialEq, Clone)]
16#[serde(rename_all = "camelCase", bound = "H: ScheduleHydrations")]
17pub struct SchedulePostseasonSeriesResponse<H: ScheduleHydrations> {
18 pub copyright: Copyright,
19 pub series: Vec<ScheduleSeries<H>>,
20}
21
22#[derive(Debug, Deserialize, PartialEq, Clone)]
23#[serde(rename_all = "camelCase", bound = "H: ScheduleHydrations")]
24pub struct ScheduleSeries<H: ScheduleHydrations> {
25 pub games: Vec<ScheduleGame<H>>,
26 #[serde(rename = "series")]
27 pub data: SeriesData,
28}
29
30#[derive(Debug, Deserialize, PartialEq, Clone)]
31#[serde(rename_all = "camelCase")]
32pub struct SeriesData {
33 #[serde(rename = "id", deserialize_with = "series_number_from_id")]
34 pub series_number: u32,
35 pub is_default: bool,
36 pub game_type: GameType,
37}
38
39pub fn series_number_from_id<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
44 let str = String::deserialize(deserializer)?;
45 let (_game_type, series_number) = str.split_once('_').ok_or_else(|| D::Error::custom("Malformed id, expected format '{game_type}_{series_number}'"))?;
46 let series_number: u32 = series_number.parse().map_err(D::Error::custom)?;
47 Ok(series_number)
48}
49
50#[derive(Builder)]
51#[builder(derive(Into))]
52pub struct SchedulePostseasonSeriesRequest<H: ScheduleHydrations> {
53 #[builder(into)]
54 season: SeasonId,
55 #[builder(into)]
56 sport_id: Option<SportId>,
57 #[builder(into)]
58 team_id: Option<TeamId>,
59 game_types: Option<Vec<GameType>>,
60 series_number: Option<u32>,
61 #[builder(skip)]
62 _marker: PhantomData<H>,
63}
64
65impl<H: ScheduleHydrations, S: schedule_postseason_series_request_builder::State + schedule_postseason_series_request_builder::IsComplete> crate::request::RequestURLBuilderExt for SchedulePostseasonSeriesRequestBuilder<H, S> {
66 type Built = SchedulePostseasonSeriesRequest<H>;
67}
68
69impl<H: ScheduleHydrations> Display for SchedulePostseasonSeriesRequest<H> {
70 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
71 let hydrations = Some(H::hydration_text(&())).filter(|s| !s.is_empty());
72
73 write!(
74 f,
75 "http://statsapi.mlb.com/api/v1/schedule/postseason/series{params}",
76 params = gen_params! {
77 "season": self.season,
78 "sportId"?: self.sport_id,
79 "teamId"?: self.team_id,
80 "gameTypes"?: self.game_types.as_ref().map(|x| x.iter().map(|x| format!("{x:?}")).join(",")),
81 "seriesNumber"?: self.series_number,
82 "hydrate"?: hydrations,
83 }
84 )
85 }
86}
87
88impl<H: ScheduleHydrations> RequestURL for SchedulePostseasonSeriesRequest<H> {
89 type Response = SchedulePostseasonSeriesResponse<H>;
90}