Skip to main content

mlb_api/requests/
sport.rs

1use crate::types::Copyright;
2use crate::request::RequestURL;
3use bon::Builder;
4use serde::Deserialize;
5use std::fmt::{Display, Formatter};
6use crate::cache::{Requestable};
7#[cfg(feature = "cache")]
8use crate::{rwlock_const_new, RwLock, cache::CacheTable};
9
10#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
11#[serde(rename_all = "camelCase")]
12pub struct SportsResponse {
13	pub copyright: Copyright,
14	pub sports: Vec<Sport>,
15}
16
17id!(SportId { id: u32 });
18
19impl SportId {
20	/// This is only here because we can rest assured that it won't ever go away.
21	pub const MLB: Self = Self::new(1);
22}
23
24impl Default for SportId {
25	fn default() -> Self {
26		Self::MLB
27	}
28}
29
30#[derive(Builder)]
31#[builder(derive(Into))]
32pub struct SportsRequest {
33	#[builder(into)]
34	id: Option<SportId>,
35}
36
37impl<S: sports_request_builder::State + sports_request_builder::IsComplete> crate::request::RequestURLBuilderExt for SportsRequestBuilder<S> {
38	type Built = SportsRequest;
39}
40
41impl Display for SportsRequest {
42	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
43		write!(f, "http://statsapi.mlb.com/api/v1/sports{}", gen_params! { "sportId"?: self.id })
44	}
45}
46
47impl RequestURL for SportsRequest {
48	type Response = SportsResponse;
49}
50
51#[derive(Debug, Deserialize, Clone)]
52#[serde(rename_all = "camelCase")]
53pub struct Sport {
54	pub code: String,
55	pub name: String,
56	pub abbreviation: String,
57	#[serde(rename = "activeStatus")]
58	pub active: bool,
59	#[serde(flatten)]
60	pub id: SportId,
61}
62
63id_only_eq_impl!(Sport, id);
64
65#[cfg(feature = "cache")]
66static CACHE: RwLock<CacheTable<Sport>> = rwlock_const_new(CacheTable::new());
67
68impl Requestable for Sport {
69	type Identifier = SportId;
70	type URL = SportsRequest;
71
72	fn id(&self) -> &Self::Identifier {
73		&self.id
74	}
75
76	#[cfg(feature = "aggressive_cache")]
77	fn url_for_id(_id: &Self::Identifier) -> Self::URL {
78		SportsRequest::builder().build()
79	}
80
81	#[cfg(not(feature = "aggressive_cache"))]
82	fn url_for_id(id: &Self::Identifier) -> Self::URL {
83		SportsRequest::builder().id(*id).build()
84	}
85
86	fn get_entries(response: <Self::URL as RequestURL>::Response) -> impl IntoIterator<Item=Self>
87	where
88		Self: Sized
89	{
90		response.sports
91	}
92
93	#[cfg(feature = "cache")]
94	fn get_cache_table() -> &'static RwLock<CacheTable<Self>>
95	where
96		Self: Sized
97	{
98		&CACHE
99	}
100}
101
102entrypoint!(SportId => Sport);
103entrypoint!(Sport.id => Sport);
104
105#[cfg(test)]
106mod tests {
107	use super::*;
108	use crate::request::RequestURLBuilderExt;
109
110	#[tokio::test]
111	async fn parse_all_sports() {
112		let _result = SportsRequest::builder().build_and_get().await.unwrap();
113	}
114}