#[macro_export]
#[doc(hidden)]
macro_rules! __stats__stat_type_definition {
($parent_name:ident => $vis:vis struct $name:ident { $stat_type:ident => [$($stat_group:ident),+] }) => {
$crate::macro_use::pastey::paste! {
#[derive(Debug, PartialEq, Clone)]
$vis struct $name {
$($vis [< $stat_group:snake >]: ::std::boxed::Box<<$crate::stats::stat_types::[<__ $stat_type StatTypeStats>] as $crate::stats::StatTypeStats>::$stat_group>),+
}
impl [<__ $parent_name Split Parser>] for $name {
fn parse(parsed_stats: &mut $crate::stats::parse::__ParsedStats) -> ::core::result::Result<Self, ::std::string::String> {
Ok(Self {
$([<$stat_group:snake>]: ::std::boxed::Box::new(
$crate::stats::parse::make_stat_split::<<$crate::stats::stat_types::[< __ $stat_type StatTypeStats >] as $crate::stats::StatTypeStats>::$stat_group>(
parsed_stats, ::core::stringify!([<$stat_type:lower_camel>]), $crate::meta::StatGroup::$stat_group
).map_err(|e| ::std::string::ToString::to_string(&e))?
)),+
})
}
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __stats__base_hydration_text {
([$first_stat_type:ident $(, $stat_type:ident)* $(,)?] [$first_stat_group:ident $(, $stat_group:ident)* $(,)?]) => {
$crate::macro_use::pastey::paste! {
::core::concat!(
"type=[",
::core::stringify!([<$first_stat_type:lower_camel>]),
$(",", ::core::stringify!([<$stat_type:lower_camel>]), )*
"],group=[",
::core::stringify!([<$first_stat_group:lower_camel>]),
$(",", ::core::stringify!([<$stat_group:lower_camel>]), )*
"]"
)
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __stats__needle_haystack_metrics {
([$($haystack:ident),+ $(,)?] => { $($t:tt)* }) => {
$crate::__stats__needle_haystack_metrics!([$($haystack),+] => { $($t)* } else {});
};
([MetricLog $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([MetricAverages $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([$first:ident $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$crate::__stats__needle_haystack_metrics!([$($haystack),*] => { $($t1)* } else { $($t2)* });
};
([$(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => { $($t2)* };
}
#[macro_export]
#[doc(hidden)]
macro_rules! __stats__needle_haystack_date_range {
([$($haystack:ident),+ $(,)?] => { $($t:tt)* }) => {
$crate::__stats__needle_haystack_date_range!([$($haystack),+] => { $($t)* } else {});
};
([ByDateRange $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([$first:ident $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$crate::__stats__needle_haystack_date_range!([$($haystack),*] => { $($t1)* } else { $($t2)* });
};
([$(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => { $($t2)* };
}
#[macro_export]
#[doc(hidden)]
macro_rules! __stats__needle_haystack_situations {
([$($haystack:ident),+ $(,)?] => { $($t:tt)* }) => {
$crate::__stats__needle_haystack_situations!([$($haystack),+] => { $($t)* } else {});
};
([StatSplits $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([StatSplitsAdvanced $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([$first:ident $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$crate::__stats__needle_haystack_situations!([$($haystack),*] => { $($t1)* } else { $($t2)* });
};
([$(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => { $($t2)* };
}
#[macro_export]
#[doc(hidden)]
macro_rules! __stats__needle_haystack_games_back {
([$($haystack:ident),+ $(,)?] => { $($t:tt)* }) => {
$crate::__stats__needle_haystack_games_back!([$($haystack),+] => { $($t)* } else {});
};
([LastXGames $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([$first:ident $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$crate::__stats__needle_haystack_games_back!([$($haystack),*] => { $($t1)* } else { $($t2)* });
};
([$(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => { $($t2)* };
}
#[macro_export]
#[doc(hidden)]
macro_rules! __stats__needle_haystack_opponent_player {
([$($haystack:ident),+ $(,)?] => { $($t:tt)* }) => {
$crate::__stats__needle_haystack_opponent_player!([$($haystack),+] => { $($t)* } else {});
};
([VsPlayer5Y $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([VsPlayerTotal $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([VsPlayer $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$($t1)*
};
([$first:ident $(, $haystack:ident)* $(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => {
$crate::__stats__needle_haystack_opponent_player!([$($haystack),*] => { $($t1)* } else { $($t2)* });
};
([$(,)?] => { $($t1:tt)* } else { $($t2:tt)* }) => { $($t2)* };
}
#[macro_export]
#[doc(hidden)]
macro_rules! __stats__request_data {
(@ metrics [$($stat_type:ident),+] $(#[$m:meta])* $vis:vis struct $name:ident { $($field_tt:tt)* } $($impl_tt:tt)*) => {
$crate::macro_use::pastey::paste! {
$crate::__stats__needle_haystack_metrics! { [$($stat_type),+] => {
$crate::__stats__request_data! { @ date_range [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
metrics: ::std::vec::Vec<$crate::meta::MetricId>,
}
$($impl_tt)*
impl<S: [<$name:snake _builder>]::State> [<$name Builder>]<S> {
pub fn metric(self, metric: impl ::core::convert::Into<$crate::meta::MetricId>) -> [<$name Builder>]<[<$name:snake _builder>]::SetMetrics<S>>
where
S::Metrics: [<$name:snake _builder>]::IsUnset
{
self.metrics(::std::vec![::core::convert::Into::into(metric)])
}
}
}
} else {
$crate::__stats__request_data! { @ date_range [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
}
$($impl_tt)*
}
}}
}
};
(@ date_range [$($stat_type:ident),+] $(#[$m:meta])* $vis:vis struct $name:ident { $($field_tt:tt)* } $($impl_tt:tt)*) => {
$crate::macro_use::pastey::paste! {
$crate::__stats__needle_haystack_date_range!{[$($stat_type),+] => {
$crate::__stats__request_data! { @ situations [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
date_range: $crate::NaiveDateRange,
}
$($impl_tt)*
}
} else {
$crate::__stats__request_data! { @ situations [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
}
$($impl_tt)*
}
}}
}
};
(@ situations [$($stat_type:ident),+] $(#[$m:meta])* $vis:vis struct $name:ident { $($field_tt:tt)* } $($impl_tt:tt)*) => {
$crate::macro_use::pastey::paste! {
$crate::__stats__needle_haystack_situations!{[$($stat_type),+] => {
$crate::__stats__request_data! { @ games_back [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
situations: ::std::vec::Vec<$crate::meta::SituationCodeId>,
#[builder(default)]
situation_filter: $crate::meta::SituationCodeFilter,
}
$($impl_tt)*
impl<S: [<$name:snake _builder>]::State> [<$name Builder>]<S> {
#[allow(dead_code, reason = "could be used by the end user")]
pub fn situation(self, situation: impl ::core::convert::Into<$crate::meta::SituationCodeId>) -> [<$name Builder>]<[<$name:snake _builder>]::SetSituations<S>>
where
S::Situations: [<$name:snake _builder>]::IsUnset
{
self.situations(::std::vec![::core::convert::Into::into(situation)])
}
}
}
} else {
$crate::__stats__request_data! { @ games_back [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
}
$($impl_tt)*
}
}}
}
};
(@ games_back [$($stat_type:ident),+] $(#[$m:meta])* $vis:vis struct $name:ident { $($field_tt:tt)* } $($impl_tt:tt)*) => {
$crate::macro_use::pastey::paste! {
$crate::__stats__needle_haystack_games_back!{[$($stat_type),+] => {
$crate::__stats__request_data! { @ opponent_player [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
games_back: usize,
}
$($impl_tt)*
}
} else {
$crate::__stats__request_data! { @ opponent_player [$($stat_type),+]
$(#[$m])*
$vis struct $name {
$($field_tt)*
}
$($impl_tt)*
}
}}
}
};
(@ opponent_player [$($stat_type:ident),+] $(#[$m:meta])* $vis:vis struct $name:ident { $($field_tt:tt)* } $($impl_tt:tt)*) => {
$crate::macro_use::pastey::paste! {
$crate::__stats__needle_haystack_opponent_player!{[$($stat_type),+] => {
$(#[$m])*
$vis struct $name {
$($field_tt)*
#[builder(into)]
opponent_player: $crate::person::PersonId,
}
$($impl_tt)*
} else {
$(#[$m])*
$vis struct $name {
$($field_tt)*
}
$($impl_tt)*
// }
}}
}
};
($vis:vis $name:ident [$($stat_type:ident),+]) => {
$crate::macro_use::pastey::paste! {
$crate::__stats__request_data! { @ metrics [$($stat_type),+]
#[derive($crate::macro_use::bon::Builder)]
#[builder(derive(Into))]
#[allow(unused, reason = "could be unused by the end user")]
$vis struct [<$name RequestData>] {
#[builder(default)]
game_type: $crate::meta::GameType,
#[builder(into)]
season: ::core::option::Option<$crate::season::SeasonId>,
team_ids: ::core::option::Option<::std::vec::Vec<$crate::team::TeamId>>,
sport_ids: ::core::option::Option<::std::vec::Vec<$crate::sport::SportId>>,
league_ids: ::core::option::Option<::std::vec::Vec<$crate::league::LeagueId>>,
limit: Option<usize>,
#[builder(default)]
player_pool: $crate::PlayerPool,
}
#[allow(unused, reason = "may be used by end user")]
impl<S: [<$name:snake _request_data_builder>]::State> [<$name RequestDataBuilder>]<S> {
pub fn team_id(self, team_id: impl ::core::convert::Into<$crate::team::TeamId>) -> [<$name RequestDataBuilder>]<[<$name:snake _request_data_builder>]::SetTeamIds<S>>
where
S::TeamIds: [<$name:snake _request_data_builder>]::IsUnset
{
self.team_ids(::std::vec![::core::convert::Into::into(team_id)])
}
pub fn sport_id(self, sport_id: impl ::core::convert::Into<$crate::sport::SportId>) -> [<$name RequestDataBuilder>]<[<$name:snake _request_data_builder>]::SetSportIds<S>>
where
S::SportIds: [<$name:snake _request_data_builder>]::IsUnset
{
self.sport_ids(::std::vec![::core::convert::Into::into(sport_id)])
}
pub fn league_id(self, league_id: impl ::core::convert::Into<$crate::league::LeagueId>) -> [<$name RequestDataBuilder>]<[<$name:snake _request_data_builder>]::SetLeagueIds<S>>
where
S::LeagueIds: [<$name:snake _request_data_builder>]::IsUnset
{
self.league_ids(::std::vec![::core::convert::Into::into(league_id)])
}
}
}
impl ::core::fmt::Display for [<$name RequestData>] {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
use $crate::macro_use::itertools::Itertools;
::core::fmt::Write::write_fmt(f, ::core::format_args!("gameType={:?},", self.game_type))?;
if let ::core::option::Option::Some(season) = self.season {
::core::fmt::Write::write_fmt(f, ::core::format_args!("season={},", season))?;
}
if let ::core::option::Option::Some(ids) = ::core::option::Option::as_ref(&self.team_ids) {
::core::fmt::Write::write_fmt(f, ::core::format_args!("teamIds=[{}],", ids.iter().join(",")))?;
}
if let ::core::option::Option::Some(ids) = ::core::option::Option::as_ref(&self.sport_ids) {
::core::fmt::Write::write_fmt(f, ::core::format_args!("sportIds=[{}],", ids.iter().join(",")))?;
}
if let ::core::option::Option::Some(ids) = ::core::option::Option::as_ref(&self.league_ids) {
::core::fmt::Write::write_fmt(f, ::core::format_args!("leagueIds=[{}],", ids.iter().join(",")))?;
}
::core::fmt::Write::write_fmt(f, ::core::format_args!("playerPool={},", self.player_pool))?;
if let ::core::option::Option::Some(limit) = ::core::option::Option::as_ref(&self.limit) {
::core::fmt::Write::write_fmt(f, ::core::format_args!("limit={}", limit))?;
}
$crate::__stats__needle_haystack_metrics! { [$($stat_type),+] => {
::core::fmt::Write::write_fmt(f, ::core::format_args!("metrics={},", self.metrics.iter().join(",")))?;
} else {}}
$crate::__stats__needle_haystack_date_range! { [$($stat_type),+] => {
::core::fmt::Write::write_fmt(f, ::core::format_args!("startDate={},endDate={},", self.date_range.start().format($crate::MLB_API_DATE_FORMAT), self.date_range.end().format($crate::MLB_API_DATE_FORMAT)))?;
} else {}}
$crate::__stats__needle_haystack_situations! { [$($stat_type),+] => {
::core::fmt::Write::write_fmt(f, ::core::format_args!("sitCodes=[{}],combineSits={},", self.situations.iter().join(","), self.situation_filter == $crate::meta::SituationCodeFilter::All))?;
} else {}}
$crate::__stats__needle_haystack_opponent_player! { [$($stat_type),+] => {
::core::fmt::Write::write_fmt(f, ::core::format_args!("opposingPlayerId={},", self.opponent_player))?;
} else {}}
Ok(())
}
}
$crate::__stats__needle_haystack_metrics! { [$($stat_type),+] => {} else {
$crate::__stats__needle_haystack_date_range! { [$($stat_type),+] => {} else {
$crate::__stats__needle_haystack_situations! { [$($stat_type),+] => {} else {
$crate::__stats__needle_haystack_opponent_player! { [$($stat_type),+] => {} else {
impl ::core::default::Default for [<$name RequestData>] {
fn default() -> Self {
[<$name RequestDataBuilder>]::<[<$name:snake _request_data_builder>]::Empty>::build(Self::builder())
}
}
}}
}}
}}
}}
impl $name {
#[allow(unused, reason = "might use RequestData::builder() instead")]
pub fn builder() -> [<$name RequestDataBuilder>] {
[<$name RequestData>]::builder()
}
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __stats0 {
($vis:vis struct $name:ident {
[$($stat_type:ident),+ $(,)?] + $stat_groups:tt
}) => {
$crate::macro_use::pastey::paste! {
#[derive(Debug, PartialEq, Clone)]
$vis struct $name {
$($vis [<$stat_type:snake>]: [<$name $stat_type Split>],)*
}
#[doc(hidden)]
trait [<__ $name Split Parser>] {
fn parse(parsed_stats: &mut $crate::stats::parse::__ParsedStats) -> ::core::result::Result<Self, ::std::string::String>
where
Self: Sized;
}
$($crate::__stats__stat_type_definition!($name => $vis struct [<$name $stat_type Split>] { $stat_type => $stat_groups });)+
impl<'de> $crate::macro_use::serde::Deserialize<'de> for $name {
fn deserialize<D: $crate::macro_use::serde::de::Deserializer<'de>>(deserializer: D) -> ::core::result::Result<Self, D::Error>
where
Self: Sized
{
let mut parsed_stats: $crate::stats::parse::__ParsedStats = <$crate::stats::parse::__ParsedStats as $crate::macro_use::serde::Deserialize>::deserialize(deserializer)?;
Ok(Self {
$([<$stat_type:snake>]: <[<$name $stat_type Split>] as [<__ $name Split Parser>]>::parse(&mut parsed_stats).map_err(<D::Error as $crate::macro_use::serde::de::Error>::custom)?),+
})
}
}
$crate::__stats__request_data!($vis $name [$($stat_type),+]);
impl $crate::hydrations::Hydrations for $name {
type RequestData = [<$name RequestData>];
fn hydration_text(data: &<Self as $crate::hydrations::Hydrations>::RequestData) -> ::std::borrow::Cow<'static, str> {
let base: &'static str = $crate::__stats__base_hydration_text!([$($stat_type),+] $stat_groups);
let data: ::std::string::String = ::std::string::ToString::to_string(data);
if str::is_empty(&*data) {
::std::borrow::Cow::Borrowed(base)
} else {
::std::borrow::Cow::Owned(::std::format!("{base},{data}"))
}
}
}
}
};
}
#[macro_export]
macro_rules! single_stat {
($stat_type:ident + $stat_group:ident for $person_id:expr) => {
$crate::single_stat! { $stat_type + $stat_group for $person_id; with |builder| builder }
};
($stat_type:ident + $stat_group:ident for $person_id:expr; with |$builder:ident| $builder_expr:expr) => {{
$crate::macro_use::pastey::paste! {
$crate::person_hydrations! {
struct [<$stat_type $stat_group SingleStatHydrations >] {
stats: { [$stat_type] + [$stat_group] },
}
}
async {
let request = $crate::person::PersonRequest::<[<$stat_type $stat_group SingleStatHydrations >]>::builder().hydrations([<$stat_type $stat_group SingleStatHydrations>]::builder().stats({
let $builder = [<$stat_type $stat_group SingleStatHydrationsInlineStats>]::builder();
$builder_expr
})).id($person_id).build();
let response = $crate::request::RequestURL::get(&request).await;
response.and_then::<[$crate::person::Person<[<$stat_type $stat_group SingleStatHydrations>]>; 1], _>(|response|
response.people.try_into().map_err(|_| $crate::request::Error::MLB($crate::MLBError::new("Expected one person in a single stat response".to_owned())))
).map(|[person]| match person {
$crate::person::Person::Ballplayer($crate::person::Ballplayer { inner, .. }) => *inner,
$crate::person::Person::Regular(inner) => inner,
}.extras.stats.[<$stat_type:snake>].[<$stat_group:snake>])
}
}
}};
}
#[macro_export]
macro_rules! stats_hydrations {
($($t:tt)*) => {
$crate::__stats0! { $($t)* }
};
}