mlb_api/endpoints/meta/kinds/
baseball_stats.rs

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