mlb_api/endpoints/meta/kinds/
game_status.rs1use crate::endpoints::meta::{MetaEndpointUrl, MetaKind};
2use derive_more::{Deref, DerefMut, Display, From};
3use serde::Deserialize;
4use std::ops::{Deref, DerefMut};
5use strum::EnumTryAs;
6use crate::cache::{EndpointEntryCache, HydratedCacheTable};
7use crate::{rwlock_const_new, RwLock};
8use crate::endpoints::StatsAPIUrl;
9
10#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
11#[serde(rename_all = "camelCase")]
12pub struct IdentifiableGameStatus {
13 #[serde(rename = "detailedState")] pub id: GameStatusId,
14}
15
16#[repr(transparent)]
17#[derive(Debug, Deserialize, Deref, Display, PartialEq, Eq, Clone, Hash)]
18pub struct GameStatusId(String);
19
20#[derive(Debug, Deserialize, Deref, DerefMut, PartialEq, Eq, Clone)]
21#[serde(rename_all = "camelCase")]
22pub struct HydratedGameStatus {
23 pub abstract_game_state: String,
24 pub coded_game_state: String,
25 pub status_code: String,
26 pub reason: Option<String>,
27 pub abstract_game_code: String,
28
29 #[deref]
30 #[deref_mut]
31 #[serde(flatten)]
32 inner: IdentifiableGameStatus,
33}
34
35#[derive(Debug, Deserialize, Eq, Clone, From, EnumTryAs)]
36#[serde(untagged)]
37pub enum GameStatus {
38 Hydrated(HydratedGameStatus),
39 Identifiable(IdentifiableGameStatus),
40}
41
42impl Deref for GameStatus {
43 type Target = IdentifiableGameStatus;
44
45 fn deref(&self) -> &Self::Target {
46 match self {
47 Self::Hydrated(inner) => inner,
48 Self::Identifiable(inner) => inner,
49 }
50 }
51}
52
53impl DerefMut for GameStatus {
54 fn deref_mut(&mut self) -> &mut Self::Target {
55 match self {
56 Self::Hydrated(inner) => inner,
57 Self::Identifiable(inner) => inner,
58 }
59 }
60}
61
62impl PartialEq for GameStatus {
63 fn eq(&self, other: &Self) -> bool {
64 self.id == other.id
65 }
66}
67
68impl MetaKind for GameStatus {
69 const ENDPOINT_NAME: &'static str = "gameStatus";
70}
71
72static CACHE: RwLock<HydratedCacheTable<GameStatus>> = rwlock_const_new(HydratedCacheTable::new());
73
74impl EndpointEntryCache for GameStatus {
75 type HydratedVariant = HydratedGameStatus;
76 type Identifier = GameStatusId;
77 type URL = MetaEndpointUrl<Self>;
78
79 fn into_hydrated_variant(self) -> Option<Self::HydratedVariant> {
80 self.try_as_hydrated()
81 }
82
83 fn id(&self) -> &Self::Identifier {
84 &self.id
85 }
86
87 fn url_for_id(_id: &Self::Identifier) -> Self::URL {
88 MetaEndpointUrl::new()
89 }
90
91 fn get_entries(response: <Self::URL as StatsAPIUrl>::Response) -> impl IntoIterator<Item=Self>
92 where
93 Self: Sized
94 {
95 response.entries
96 }
97
98 fn get_hydrated_cache_table() -> &'static RwLock<HydratedCacheTable<Self>>
99 where
100 Self: Sized
101 {
102 &CACHE
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use crate::endpoints::StatsAPIUrl;
109 use crate::endpoints::meta::MetaEndpointUrl;
110
111 #[tokio::test]
112 async fn parse_meta() {
113 let _response = MetaEndpointUrl::<super::GameStatus>::new().get().await.unwrap();
114 }
115}