use crate::Copyright;
use crate::meta::GameType;
use crate::request::RequestURL;
use crate::schedule::{ScheduleGame, ScheduleHydrations};
use crate::season::SeasonId;
use crate::sport::SportId;
use crate::team::TeamId;
use bon::Builder;
use itertools::Itertools;
use serde::de::Error;
use serde::{Deserialize, Deserializer};
use std::fmt::{Display, Formatter};
use std::marker::PhantomData;
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase", bound = "H: ScheduleHydrations")]
pub struct SchedulePostseasonSeriesResponse<H: ScheduleHydrations> {
pub copyright: Copyright,
pub series: Vec<ScheduleSeries<H>>,
}
#[derive(Debug, Deserialize, PartialEq, Clone)]
#[serde(rename_all = "camelCase", bound = "H: ScheduleHydrations")]
pub struct ScheduleSeries<H: ScheduleHydrations> {
pub games: Vec<ScheduleGame<H>>,
#[serde(rename = "series")]
pub data: SeriesData,
}
#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SeriesData {
#[serde(rename = "id", deserialize_with = "series_number_from_id")]
pub series_number: u32,
pub is_default: bool,
pub game_type: GameType,
}
pub fn series_number_from_id<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
let str = String::deserialize(deserializer)?;
let (_game_type, series_number) = str.split_once('_').ok_or_else(|| D::Error::custom("Malformed id, expected format '{game_type}_{series_number}'"))?;
let series_number: u32 = series_number.parse().map_err(D::Error::custom)?;
Ok(series_number)
}
#[derive(Builder)]
#[builder(derive(Into))]
pub struct SchedulePostseasonSeriesRequest<H: ScheduleHydrations> {
#[builder(into)]
season: SeasonId,
#[builder(into)]
sport_id: Option<SportId>,
#[builder(into)]
team_id: Option<TeamId>,
game_types: Option<Vec<GameType>>,
series_number: Option<u32>,
#[builder(skip)]
_marker: PhantomData<H>,
}
impl<H: ScheduleHydrations, S: schedule_postseason_series_request_builder::State + schedule_postseason_series_request_builder::IsComplete> crate::request::RequestURLBuilderExt for SchedulePostseasonSeriesRequestBuilder<H, S> {
type Built = SchedulePostseasonSeriesRequest<H>;
}
impl<H: ScheduleHydrations> Display for SchedulePostseasonSeriesRequest<H> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let hydrations = Some(H::hydration_text(&())).filter(|s| !s.is_empty());
write!(
f,
"http://statsapi.mlb.com/api/v1/schedule/postseason/series{params}",
params = gen_params! {
"season": self.season,
"sportId"?: self.sport_id,
"teamId"?: self.team_id,
"gameTypes"?: self.game_types.as_ref().map(|x| x.iter().map(|x| format!("{x:?}")).join(",")),
"seriesNumber"?: self.series_number,
"hydrate"?: hydrations,
}
)
}
}
impl<H: ScheduleHydrations> RequestURL for SchedulePostseasonSeriesRequest<H> {
type Response = SchedulePostseasonSeriesResponse<H>;
}