Skip to main content

mlb_api/requests/schedule/postseason/
series.rs

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