mlb_api/requests/stats/
derived.rs1use crate::stats::raw::OmittedStatError;
2use crate::stats::units::{CountingStat, InningsPitched, PercentageStat, ThreeDecimalPlaceRateStat, TwoDecimalPlaceRateStat};
3
4type Result<T, E = OmittedStatError> = core::result::Result<T, E>;
5
6macro_rules! wrap {
7 ($expr:expr) => {
8 (move || Result::<_>::Ok($expr))().unwrap_or_default()
9 };
10}
11
12#[must_use]
18pub fn avg(hits: Result<CountingStat>, at_bats: Result<CountingStat>) -> ThreeDecimalPlaceRateStat {
19 wrap!(ThreeDecimalPlaceRateStat::new(hits? as f64 / at_bats? as f64))
20}
21
22#[must_use]
28pub fn slg(total_bases: Result<CountingStat>, at_bats: Result<CountingStat>) -> ThreeDecimalPlaceRateStat {
29 wrap!(ThreeDecimalPlaceRateStat::new(total_bases? as f64 / at_bats? as f64))
30}
31
32#[must_use]
38pub fn obp(
39 hits: Result<CountingStat>,
40 base_on_balls: Result<CountingStat>,
41 intentional_walks: Result<CountingStat>,
42 hit_by_pitch: Result<CountingStat>,
43 at_bats: Result<CountingStat>,
44 sac_bunts: Result<CountingStat>,
45 sac_hits: Result<CountingStat>,
46) -> ThreeDecimalPlaceRateStat {
47 wrap!(ThreeDecimalPlaceRateStat::new((hits? + base_on_balls? + intentional_walks? + hit_by_pitch?) as f64 / (at_bats? + base_on_balls? + intentional_walks? + hit_by_pitch? + sac_bunts? + sac_hits?) as f64))
48}
49
50#[must_use]
57pub fn ops(obp: Result<ThreeDecimalPlaceRateStat>, slg: Result<ThreeDecimalPlaceRateStat>) -> ThreeDecimalPlaceRateStat {
58 wrap!(ThreeDecimalPlaceRateStat::new(*obp? + *slg?))
59}
60
61#[must_use]
67pub fn stolen_base_pct(stolen_bases: Result<CountingStat>, caught_stealing: Result<CountingStat>) -> PercentageStat {
68 wrap!(PercentageStat::new(stolen_bases? as f64 / (stolen_bases? + caught_stealing?) as f64))
69}
70
71#[must_use]
77pub fn caught_stealing_pct(stolen_bases: Result<CountingStat>, caught_stealing: Result<CountingStat>) -> PercentageStat {
78 wrap!(PercentageStat::new(caught_stealing? as f64 / (stolen_bases? + caught_stealing?) as f64))
79}
80
81#[must_use]
89pub fn babip(
90 hits: Result<CountingStat>,
91 home_runs: Result<CountingStat>,
92 at_bats: Result<CountingStat>,
93 strikeouts: Result<CountingStat>,
94 sac_flies: Result<CountingStat>,
95) -> ThreeDecimalPlaceRateStat {
96 wrap!(ThreeDecimalPlaceRateStat::new((hits? - home_runs?) as f64 / (at_bats? - strikeouts? - home_runs? - sac_flies?) as f64))
97}
98
99#[must_use]
105pub fn bb_pct(base_on_balls: Result<CountingStat>, plate_appearances: Result<CountingStat>) -> PercentageStat {
106 wrap!(PercentageStat::new(base_on_balls? as f64 / plate_appearances? as f64))
107}
108
109#[must_use]
115pub fn k_pct(strikeouts: Result<CountingStat>, plate_appearances: Result<CountingStat>) -> PercentageStat {
116 wrap!(PercentageStat::new(strikeouts? as f64 / plate_appearances? as f64))
117}
118
119pub fn extra_bases(doubles: Result<CountingStat>, triples: Result<CountingStat>, home_runs: Result<CountingStat>) -> Result<CountingStat> {
121 Ok(doubles? + triples? * 2 + home_runs? * 3)
122}
123
124#[must_use]
130pub fn iso(extra_bases: Result<CountingStat>, at_bats: Result<CountingStat>) -> ThreeDecimalPlaceRateStat {
131 wrap!(ThreeDecimalPlaceRateStat::new(extra_bases? as f64 / at_bats? as f64))
132}
133
134#[must_use]
140pub fn strikeout_to_walk_ratio(strikeouts: Result<CountingStat>, base_on_balls: Result<CountingStat>) -> TwoDecimalPlaceRateStat {
141 wrap!(TwoDecimalPlaceRateStat::new(strikeouts? as f64 / base_on_balls? as f64))
142}
143
144#[must_use]
150pub fn whiff_pct(whiffs: Result<CountingStat>, total_swings: Result<CountingStat>) -> PercentageStat {
151 wrap!(PercentageStat::new(whiffs? as f64 / total_swings? as f64))
152}
153
154#[must_use]
159pub fn era(earned_runs: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
160 wrap!(TwoDecimalPlaceRateStat::new(earned_runs? as f64 * 27.0 / innings_pitched?.as_outs() as f64))
161}
162
163#[must_use]
168pub fn whip(hits: Result<CountingStat>, base_on_balls: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
169 wrap!(TwoDecimalPlaceRateStat::new(((base_on_balls? + hits?) as f64) / innings_pitched?.as_fraction()))
170}
171
172#[must_use]
177pub fn win_pct(wins: Result<CountingStat>, losses: Result<CountingStat>) -> ThreeDecimalPlaceRateStat {
178 wrap!(ThreeDecimalPlaceRateStat::new(wins? as f64 / (wins? + losses?) as f64))
179}
180
181#[must_use]
188pub fn pitches_per_inning_pitched(number_of_pitches: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
189 wrap!(TwoDecimalPlaceRateStat::new(number_of_pitches? as f64 / innings_pitched?.as_fraction()))
190}
191
192#[must_use]
198pub fn k_per_9(strikeouts: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
199 wrap!(TwoDecimalPlaceRateStat::new(strikeouts? as f64 * 27.0 / innings_pitched?.as_outs() as f64))
200}
201
202#[must_use]
208pub fn bb_per_9(base_on_balls: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
209 wrap!(TwoDecimalPlaceRateStat::new(base_on_balls? as f64 * 27.0 / innings_pitched?.as_outs() as f64))
210}
211
212#[must_use]
217pub fn hits_per_9(hits: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
218 wrap!(TwoDecimalPlaceRateStat::new(hits? as f64 * 27.0 / innings_pitched?.as_outs() as f64))
219}
220
221#[must_use]
226pub fn runs_scored_per_9(runs: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
227 wrap!(TwoDecimalPlaceRateStat::new(runs? as f64 * 27.0 / innings_pitched?.as_outs() as f64))
228}
229
230#[must_use]
235pub fn home_runs_per_9(home_runs: Result<CountingStat>, innings_pitched: Result<InningsPitched>) -> TwoDecimalPlaceRateStat {
236 wrap!(TwoDecimalPlaceRateStat::new(home_runs? as f64 / innings_pitched?.as_outs() as f64))
237}