mlb_api/requests/person/
stats.rs1use crate::game::GameId;
4use crate::person::PersonId;
5use crate::Copyright;
6use bon::Builder;
7use serde::Deserialize;
8use std::fmt::{Display, Formatter};
9use serde::de::{Deserializer, Error};
10use crate::stats::raw::PlayStat;
11use crate::request::RequestURL;
12use crate::meta::StatGroup;
13use crate::stats::parse::{__ParsedStats, make_stat_split};
14use crate::stats::raw::{fielding, hitting, pitching};
15use crate::stats::wrappers::{AccumulatedVsPlayerMatchup, WithNone};
16
17#[derive(Debug, Deserialize, PartialEq, Clone)]
18pub struct PersonSingleGameStatsResponse {
19 pub copyright: Copyright,
20 #[serde(flatten)]
21 pub stats: SingleGameStats,
22}
23
24#[derive(Builder)]
25#[builder(derive(Into))]
26pub struct PersonSingleGameStatsRequest {
27 #[builder(into)]
28 person_id: PersonId,
29 #[builder(into)]
30 game_id: GameId,
31}
32
33impl<S: person_single_game_stats_request_builder::State + person_single_game_stats_request_builder::IsComplete> crate::request::RequestURLBuilderExt for PersonSingleGameStatsRequestBuilder<S> {
34 type Built = PersonSingleGameStatsRequest;
35}
36
37impl Display for PersonSingleGameStatsRequest {
38 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 write!(f, "http://statsapi.mlb.com/api/v1/people/{}/stats/game{}", self.person_id, self.game_id)
40 }
41}
42
43impl RequestURL for PersonSingleGameStatsRequest {
44 type Response = PersonSingleGameStatsResponse;
45}
46
47#[cfg(test)]
48mod tests {
49 use crate::person::stats::PersonSingleGameStatsRequest;
50 use crate::request::RequestURLBuilderExt;
51
52 #[tokio::test]
53 async fn single_sample() {
54 let _ = PersonSingleGameStatsRequest::builder()
55 .person_id(660_271)
56 .game_id(776_562)
57 .build_and_get()
58 .await
59 .unwrap();
60 }
61}
62
63#[derive(Debug, PartialEq, Clone)]
64pub struct SingleGameStats {
65 pub game_log: SingleGameStatsSimplifiedGameLogSplit,
66 pub vs_player5_y: SingleGameStatsVsPlayer5YSplit,
67 pub play_log: SingleGameStatsSimplifiedPlayLogSplit,
68}
69
70#[derive(Debug, PartialEq, Clone)]
71pub struct SingleGameStatsSimplifiedGameLogSplit {
72 pub hitting: Box<WithNone<hitting::__SimplifiedGameLogStatsData>>,
73 pub pitching: Box<WithNone<pitching::__SimplifiedGameLogStatsData>>,
74 pub fielding: Box<WithNone<fielding::__SimplifiedGameLogStatsData>>,
75}
76
77#[derive(Debug, PartialEq, Clone)]
78pub struct SingleGameStatsVsPlayer5YSplit {
79 pub hitting: Box<AccumulatedVsPlayerMatchup<hitting::__VsPlayerStatsData>>,
80 pub pitching: Box<AccumulatedVsPlayerMatchup<pitching::__VsPlayerStatsData>>,
81}
82
83#[derive(Debug, PartialEq, Clone)]
84pub struct SingleGameStatsSimplifiedPlayLogSplit {
85 pub hitting: Box<Vec<WithNone<PlayStat>>>,
86}
87
88impl<'de> Deserialize<'de> for SingleGameStats {
89 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
90 where
91 Self: Sized,
92 {
93 let mut parsed_stats: __ParsedStats = <__ParsedStats as Deserialize>::deserialize(deserializer)?;
94
95 Ok(Self {
96 game_log: SingleGameStatsSimplifiedGameLogSplit {
97 hitting: Box::new(
98 make_stat_split::<WithNone<hitting::__SimplifiedGameLogStatsData>>(
99 &mut parsed_stats, "gameLog", StatGroup::Hitting,
100 ).map_err(D::Error::custom)?
101 ),
102 pitching: Box::new(
103 make_stat_split::<WithNone<pitching::__SimplifiedGameLogStatsData>>(
104 &mut parsed_stats, "gameLog", StatGroup::Pitching,
105 ).map_err(D::Error::custom)?
106 ),
107 fielding: Box::new(
108 make_stat_split::<WithNone<fielding::__SimplifiedGameLogStatsData>>(
109 &mut parsed_stats, "gameLog", StatGroup::Fielding,
110 ).map_err(D::Error::custom)?
111 ),
112 },
113 vs_player5_y: SingleGameStatsVsPlayer5YSplit {
114 hitting: Box::new(
115 make_stat_split::<AccumulatedVsPlayerMatchup<hitting::__VsPlayerStatsData>>(
116 &mut parsed_stats, "vsPlayer5Y", StatGroup::Hitting,
117 ).map_err(D::Error::custom)?
118 ),
119 pitching: Box::new(
120 make_stat_split::<AccumulatedVsPlayerMatchup<pitching::__VsPlayerStatsData>>(
121 &mut parsed_stats, "vsPlayer5Y", StatGroup::Pitching,
122 ).map_err(D::Error::custom)?
123 ),
124 },
125 play_log: SingleGameStatsSimplifiedPlayLogSplit {
126 hitting: Box::new(
127 make_stat_split::<Vec<WithNone<PlayStat>>>(
128 &mut parsed_stats, "playLog", StatGroup::Hitting,
129 ).map_err(D::Error::custom)?
130 ),
131 },
132 })
133 }
134}