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