mlb_api/endpoints/conferences/
mod.rs1use 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}