mlb_api/endpoints/conferences/
mod.rs

1use crate::endpoints::StatsAPIUrl;
2use crate::endpoints::league::League;
3use crate::endpoints::sports::Sport;
4use crate::{gen_params, rwlock_const_new, RwLock};
5use crate::types::Copyright;
6use derive_more::{Deref, DerefMut, Display, From};
7use serde::Deserialize;
8use std::fmt::{Display, Formatter};
9use std::ops::{Deref, DerefMut};
10use strum::EnumTryAs;
11use crate::cache::{HydratedCacheTable, EndpointEntryCache};
12
13#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
14#[serde(rename_all = "camelCase")]
15pub struct ConferencesResponse {
16	pub copyright: Copyright,
17	pub conferences: Vec<Conference>,
18}
19
20#[derive(Debug, Deserialize, Deref, DerefMut, PartialEq, Eq, Clone)]
21#[serde(rename_all = "camelCase")]
22pub struct HydratedConference {
23	pub abbreviation: String,
24	#[serde(rename = "nameShort")]
25	pub short_name: String,
26	pub has_wildcard: bool,
27	pub league: League,
28	pub sport: Sport,
29
30	#[deref]
31	#[deref_mut]
32	#[serde(flatten)]
33	inner: IdentifiableConference,
34}
35
36#[derive(Debug, Deserialize, Deref, DerefMut, PartialEq, Eq, Clone)]
37#[serde(rename_all = "camelCase")]
38pub struct NamedConference {
39	pub name: String,
40
41	#[deref]
42	#[deref_mut]
43	#[serde(flatten)]
44	inner: IdentifiableConference,
45}
46
47#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
48pub struct IdentifiableConference {
49	pub id: ConferenceId,
50}
51
52#[repr(transparent)]
53#[derive(Debug, Deserialize, Deref, Display, PartialEq, Eq, Copy, Clone, Hash)]
54pub struct ConferenceId(u32);
55
56#[derive(Debug, Deserialize, Eq, Clone, From, EnumTryAs)]
57#[serde(untagged)]
58pub enum Conference {
59	Hydrated(HydratedConference),
60	Named(NamedConference),
61	Identifiable(IdentifiableConference),
62}
63
64impl Deref for Conference {
65	type Target = IdentifiableConference;
66
67	fn deref(&self) -> &Self::Target {
68		match self {
69			Self::Hydrated(inner) => inner,
70			Self::Named(inner) => inner,
71			Self::Identifiable(inner) => inner,
72		}
73	}
74}
75
76impl DerefMut for Conference {
77	fn deref_mut(&mut self) -> &mut Self::Target {
78		match self {
79			Self::Hydrated(inner) => inner,
80			Self::Named(inner) => inner,
81			Self::Identifiable(inner) => inner,
82		}
83	}
84}
85
86impl PartialEq for Conference {
87	fn eq(&self, other: &Self) -> bool {
88		self.id == other.id
89	}
90}
91
92#[derive(Default)]
93pub struct ConferencesEndpointUrl {
94	pub conference_id: Option<ConferenceId>,
95	pub season: Option<u16>,
96}
97
98impl Display for ConferencesEndpointUrl {
99	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
100		write!(f, "http://statsapi.mlb.com/api/v1/conferences{}", gen_params! { "conferenceId"?: self.conference_id, "season"?: self.season })
101	}
102}
103
104impl StatsAPIUrl for ConferencesEndpointUrl {
105	type Response = ConferencesResponse;
106}
107
108static CACHE: RwLock<HydratedCacheTable<Conference>> = rwlock_const_new(HydratedCacheTable::new());
109
110impl EndpointEntryCache for Conference {
111	type HydratedVariant = HydratedConference;
112	type Identifier = ConferenceId;
113	type URL = ConferencesEndpointUrl;
114
115	fn into_hydrated_variant(self) -> Option<Self::HydratedVariant> {
116		self.try_as_hydrated()
117	}
118
119	fn id(&self) -> &Self::Identifier {
120		&self.id
121	}
122
123	fn url_for_id(id: &Self::Identifier) -> Self::URL {
124		ConferencesEndpointUrl {
125			conference_id: Some(id.clone()),
126			season: None,
127		}
128	}
129
130	fn get_entries(response: <Self::URL as StatsAPIUrl>::Response) -> impl IntoIterator<Item=Self>
131	where
132		Self: Sized
133	{
134		response.conferences
135	}
136
137	fn get_hydrated_cache_table() -> &'static RwLock<HydratedCacheTable<Self>>
138	where
139		Self: Sized
140	{
141		&CACHE
142	}
143}
144
145#[cfg(test)]
146mod tests {
147	use crate::endpoints::StatsAPIUrl;
148	use crate::endpoints::conferences::ConferencesEndpointUrl;
149
150	#[tokio::test]
151	async fn parse_all_conferences() {
152		let _response = ConferencesEndpointUrl { ..ConferencesEndpointUrl::default() }.get().await.unwrap();
153	}
154}