1use serde::de::DeserializeOwned;
29use serde::Deserialize;
30use std::convert::Infallible;
31use std::fmt::Debug;
32
33#[doc(hidden)]
34pub mod macros;
35#[doc(hidden)]
36pub mod raw;
37#[doc(hidden)]
38pub mod wrappers;
39pub mod leaders;
40#[doc(hidden)]
41mod units;
42#[doc(hidden)]
43pub mod parse;
44pub mod derived;
45
46pub use units::*;
47
48#[cfg(test)]
49mod tests;
50
51pub trait Stat: Debug + Clone + PartialEq + Default {
54 type Split: DeserializeOwned;
55
56 type TryFromSplitError;
57
58 fn from_splits(splits: impl Iterator<Item=Self::Split>) -> Result<Self, Self::TryFromSplitError> where Self: Sized;
61}
62
63pub trait RawStat: Debug + DeserializeOwned + Clone + PartialEq + Default {}
65
66impl RawStat for () {}
67impl SingletonSplitStat for () {}
68
69pub trait SingletonSplitStat: Debug + DeserializeOwned + Clone + PartialEq + Default {
71
72}
73
74impl<T: SingletonSplitStat> Stat for T {
75 type Split = Self;
76
77 type TryFromSplitError = &'static str;
78
79 fn from_splits(mut splits: impl Iterator<Item=Self::Split>) -> Result<Self, Self::TryFromSplitError>
80 where
81 Self: Sized
82 {
83 splits.next().ok_or("length of stat splits is not >= 1, cannot convert to unit type.")
84 }
85}
86
87#[allow(unused, reason = "might not be used by end user")]
88pub(crate) trait StatTypeStats {
89 type Hitting: Stat;
90
91 type Pitching: Stat;
92
93 type Fielding: Stat;
94
95 type Catching: Stat;
96}
97
98#[derive(Debug, Deserialize, PartialEq, Eq, Clone, Default)]
99pub struct PlayStat {
100 }
102
103pub type PitchStat = ();
105
106impl RawStat for PlayStat {}
107
108impl<T: Stat> Stat for Option<T> {
109 type Split = T::Split;
110 type TryFromSplitError = Infallible;
111
112 fn from_splits(splits: impl Iterator<Item=Self::Split>) -> Result<Self, Self::TryFromSplitError>
113 where
114 Self: Sized
115 {
116 Ok(T::from_splits(splits).ok())
117 }
118}
119
120#[doc(hidden)]
121pub mod stat_types {
122 use super::{StatTypeStats, PlayStat, PitchStat};
123 use crate::stats::raw::{catching, fielding, hitting, pitching, FieldedMatchup};
124 use crate::stats::wrappers::{AccumulatedVsPlayerMatchup, ByMonth, ByPosition, BySeason, ByWeekday, Career, Map, Map2D, SingleMatchup, WithGame, WithHomeAndAway, WithMonth, WithNone, WithPlayer, WithPositionAndSeason, WithSeason, WithTeam, WithWeekday, WithWinLoss};
125
126 macro_rules! stat_type_stats {
127 ($name:ident {
128 $hitting:ty,
129 $pitching:ty,
130 $catching:ty,
131 $fielding:ty $(,)?
132 }) => {
133 ::pastey::paste! {
134 #[doc(hidden)]
135 pub struct [<__ $name StatTypeStats>];
136
137 impl StatTypeStats for [<__ $name StatTypeStats>] {
138 type Hitting = $hitting;
139 type Pitching = $pitching;
140 type Fielding = $fielding;
141 type Catching = $catching;
142 }
143 }
144 };
145 }
146
147 stat_type_stats!(Projected { WithPlayer<hitting::__ProjectedStatsData>, WithPlayer<pitching::__ProjectedStatsData>, (), () });
151 stat_type_stats!(YearByYear { Map<WithSeason<hitting::__YearByYearStatsData>, BySeason>, Map<WithSeason<pitching::__YearByYearStatsData>, BySeason>, Map<WithSeason<catching::__YearByYearStatsData>, BySeason>, Map2D<WithPositionAndSeason<fielding::__YearByYearStatsData>, BySeason, ByPosition> });
152 stat_type_stats!(YearByYearAdvanced { Map<WithSeason<hitting::__YearByYearAdvancedStatsData>, BySeason>, Map<WithSeason<pitching::__YearByYearAdvancedStatsData>, BySeason>, (), () });
153 stat_type_stats!(Season { WithSeason<hitting::__SeasonStatsData>, WithSeason<pitching::__SeasonStatsData>, WithSeason<catching::__SeasonStatsData>, Map2D<WithPositionAndSeason<fielding::__SeasonStatsData>, BySeason, ByPosition> });
154 stat_type_stats!(Career { Career<hitting::__CareerStatsData>, Career<pitching::__CareerStatsData>, Career<catching::__CareerStatsData>, Career<fielding::__CareerStatsData> });
155 stat_type_stats!(SeasonAdvanced { WithSeason<hitting::__SeasonAdvancedStatsData>, WithSeason<pitching::__SeasonAdvancedStatsData>, (), () });
156 stat_type_stats!(CareerAdvanced { Career<hitting::__CareerAdvancedStatsData>, Career<pitching::__CareerAdvancedStatsData>, (), () });
157 stat_type_stats!(GameLog { Vec<WithGame<hitting::__GameLogStatsData>>, Vec<WithGame<pitching::__GameLogStatsData>>, Vec<WithGame<catching::__GameLogStatsData>>, Vec<WithGame<fielding::__GameLogStatsData>> });
158 stat_type_stats!(PlayLog { Vec<SingleMatchup<PlayStat>>, Vec<SingleMatchup<PlayStat>>, Vec<SingleMatchup<PlayStat>>, Vec<SingleMatchup<PlayStat>> });
159 stat_type_stats!(PitchLog { Vec<SingleMatchup<PitchStat>>, Vec<SingleMatchup<PitchStat>>, Vec<SingleMatchup<PitchStat>>, Vec<SingleMatchup<PitchStat>> });
160 stat_type_stats!(ExpectedStatistics { WithPlayer<hitting::__ExpectedStatisticsStatsData>, WithPlayer<pitching::__ExpectedStatisticsStatsData>, (), () });
165 stat_type_stats!(Sabermetrics { WithPlayer<hitting::__SabermetricsStatsData>, WithPlayer<pitching::__SabermetricsStatsData>, (), () });
166 stat_type_stats!(VsPlayer5Y { AccumulatedVsPlayerMatchup<hitting::__VsPlayerStatsData>, AccumulatedVsPlayerMatchup<pitching::__VsPlayerStatsData>, (), () });
171 stat_type_stats!(LastXGames { WithTeam<hitting::__LastXGamesStatsData>, WithTeam<pitching::__LastXGamesStatsData>, WithTeam<catching::__LastXGamesStatsData>, WithTeam<fielding::__LastXGamesStatsData> });
175 stat_type_stats!(ByDateRange { WithTeam<hitting::__ByDateRangeStatsData>, WithTeam<pitching::__ByDateRangeStatsData>, WithTeam<catching::__ByDateRangeStatsData>, WithTeam<fielding::__ByDateRangeStatsData> });
176 stat_type_stats!(ByDateRangeAdvanced { WithTeam<hitting::__ByDateRangeAdvancedStatsData>, WithTeam<pitching::__ByDateRangeAdvancedStatsData>, WithTeam<catching::__ByDateRangeAdvancedStatsData>, WithTeam<fielding::__ByDateRangeAdvancedStatsData> });
177 stat_type_stats!(ByMonth { Map<WithMonth<hitting::__ByMonthStatsData>, ByMonth>, Map<WithMonth<pitching::__ByMonthStatsData>, ByMonth>, Map<WithMonth<catching::__ByMonthStatsData>, ByMonth>, Map<WithMonth<fielding::__ByMonthStatsData>, ByMonth> });
178 stat_type_stats!(ByDayOfWeek { Map<WithWeekday<hitting::__ByDayOfWeekStatsData>, ByWeekday>, Map<WithWeekday<pitching::__ByDayOfWeekStatsData>, ByWeekday>, Map<WithWeekday<catching::__ByDayOfWeekStatsData>, ByWeekday>, Map<WithWeekday<fielding::__ByDayOfWeekStatsData>, ByWeekday> });
179 stat_type_stats!(HomeAndAway { WithHomeAndAway<hitting::__HomeAndAwayStatsData>, WithHomeAndAway<pitching::__HomeAndAwayStatsData>, WithHomeAndAway<catching::__HomeAndAwayStatsData>, WithHomeAndAway<fielding::__HomeAndAwayStatsData> });
180 stat_type_stats!(WinLoss { WithWinLoss<hitting::__WinLossStatsData>, WithWinLoss<pitching::__WinLossStatsData>, WithWinLoss<catching::__WinLossStatsData>, WithWinLoss<fielding::__WinLossStatsData> });
181 stat_type_stats!(OpponentsFaced { Vec<FieldedMatchup>, Vec<FieldedMatchup>, Vec<FieldedMatchup>, Vec<FieldedMatchup> });
185 stat_type_stats!(StatSplits { WithSeason<hitting::__StatSplitsStatsData>, WithSeason<pitching::__StatSplitsStatsData>, (), () });
186 stat_type_stats!(StatSplitsAdvanced { WithSeason<hitting::__StatSplitsAdvancedStatsData>, WithSeason<pitching::__StatSplitsAdvancedStatsData>, (), () });
187 stat_type_stats!(Boxscore { WithNone<hitting::__BoxscoreStatsData>, WithNone<pitching::__BoxscoreStatsData>, (), WithNone<fielding::__BoxscoreStatsData>, });
190}