mlb_api/requests/game/
timestamps.rs1use std::{fmt::Display, str::FromStr};
4
5use bon::Builder;
6use chrono::{DateTime, NaiveDate, NaiveDateTime, ParseError, Utc};
7use derive_more::{From, Into};
8use serde::Deserialize;
9use serde::de::Error;
10use serde_with::DisplayFromStr;
11
12use crate::game::GameId;
13use crate::request::RequestURL;
14
15pub type GameTimestampsResponse = Vec<SimplifiedTimestamp>;
16
17#[derive(Debug, PartialEq, Eq, Clone, From, Into)]
19pub struct SimplifiedTimestamp(DateTime<Utc>);
20
21impl FromStr for SimplifiedTimestamp {
22 type Err = ParseError;
23
24 fn from_str(s: &str) -> Result<Self, Self::Err> {
25 Ok(Self(NaiveDateTime::parse_from_str(s, "%Y%m%d_%H%M%S")?.and_utc()))
26 }
27}
28
29impl Display for SimplifiedTimestamp {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 write!(f, "{}", self.0.format("%Y%d%m_%H%M%S"))
32 }
33}
34
35impl<'de> Deserialize<'de> for SimplifiedTimestamp {
36 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37 where
38 D: serde::Deserializer<'de>
39 {
40 Self::from_str(&String::deserialize(deserializer)?).map_err(D::Error::custom)
41 }
42}
43
44impl SimplifiedTimestamp {
45 #[must_use]
46 pub fn now() -> Self {
47 Self(Utc::now())
48 }
49}
50
51#[derive(Builder)]
52#[builder(derive(Into))]
53pub struct GameTimestampsRequest {
54 #[builder(into)]
55 id: GameId,
56}
57
58impl Display for GameTimestampsRequest {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 write!(f, "http://statsapi.mlb.com/api/v1.1/game/{}/feed/live/timestamps", self.id)
61 }
62}
63
64impl RequestURL for GameTimestampsRequest {
65 type Response = GameTimestampsResponse;
66}
67
68impl<S: game_timestamps_request_builder::State + game_timestamps_request_builder::IsComplete> crate::request::RequestURLBuilderExt for GameTimestampsRequestBuilder<S> {
69 type Built = GameTimestampsRequest;
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::game::GameTimestampsRequest;
75 use crate::request::RequestURLBuilderExt;
76
77 #[tokio::test]
78 async fn ws_gm7_2025_timestamps() {
79 let _ = GameTimestampsRequest::builder().id(813_024).build_and_get().await.unwrap();
80 }
81}
82