mlb_api/endpoints/meta/kinds/
game_status.rs

1use 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}