mlb_api/requests/
divisions.rs1use crate::cache::Requestable;
2use crate::league::LeagueId;
3use crate::request::RequestURL;
4use crate::season::SeasonId;
5use crate::sport::SportId;
6use crate::types::Copyright;
7use bon::Builder;
8use derive_more::{Deref, DerefMut};
9use serde::Deserialize;
10use std::fmt::{Display, Formatter};
11
12#[cfg(feature = "cache")]
13use crate::{rwlock_const_new, RwLock, cache::CacheTable};
14
15#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
16#[serde(rename_all = "camelCase")]
17pub struct DivisionsResponse {
18 pub copyright: Copyright,
19 pub divisions: Vec<Division>,
20}
21
22id!(DivisionId { id: u32 });
23
24#[derive(Debug, Deserialize, Clone)]
25#[serde(rename_all = "camelCase")]
26pub struct NamedDivision {
27 pub name: String,
28 #[serde(flatten)]
29 pub id: DivisionId,
30}
31
32#[derive(Debug, Deserialize, Deref, DerefMut, Clone)]
33#[serde(rename_all = "camelCase")]
34pub struct Division {
35 #[serde(rename = "nameShort")]
36 pub short_name: String,
37 pub season: SeasonId,
38 pub abbreviation: String,
39 pub league: LeagueId,
40 pub sport: SportId,
41 pub has_wildcard: bool,
42 pub num_playoff_teams: Option<u8>,
43 pub active: bool,
44
45 #[deref]
46 #[deref_mut]
47 #[serde(flatten)]
48 inner: NamedDivision,
49}
50
51id_only_eq_impl!(Division, id);
52id_only_eq_impl!(NamedDivision, id);
53
54#[derive(Builder)]
55#[builder(derive(Into))]
56pub struct DivisionsRequest {
57 #[builder(into)]
58 division_id: Option<DivisionId>,
59 #[builder(into)]
60 league_id: Option<LeagueId>,
61 #[builder(into)]
62 sport_id: Option<SportId>,
63 #[builder(into)]
64 season: Option<SeasonId>,
65}
66
67impl<S: divisions_request_builder::State + divisions_request_builder::IsComplete> crate::request::RequestURLBuilderExt for DivisionsRequestBuilder<S> {
68 type Built = DivisionsRequest;
69}
70
71impl Display for DivisionsRequest {
72 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
73 write!(
74 f,
75 "http://statsapi.mlb.com/api/v1/divisions{}",
76 gen_params! { "divisionId"?: self.division_id, "leagueId"?: self.league_id, "sportId"?: self.sport_id, "season"?: self.season }
77 )
78 }
79}
80
81impl RequestURL for DivisionsRequest {
82 type Response = DivisionsResponse;
83}
84
85#[cfg(feature = "cache")]
86static CACHE: RwLock<CacheTable<Division>> = rwlock_const_new(CacheTable::new());
87
88impl Requestable for Division {
89 type Identifier = DivisionId;
90 type URL = DivisionsRequest;
91
92 fn id(&self) -> &Self::Identifier {
93 &self.id
94 }
95
96 #[cfg(feature = "aggressive_cache")]
97 fn url_for_id(_id: &Self::Identifier) -> Self::URL {
98 DivisionsRequest::builder().build()
99 }
100
101 #[cfg(not(feature = "aggressive_cache"))]
102 fn url_for_id(id: &Self::Identifier) -> Self::URL {
103 DivisionsRequest::builder().division_id(*id).build()
104 }
105
106 fn get_entries(response: <Self::URL as RequestURL>::Response) -> impl IntoIterator<Item=Self>
107 where
108 Self: Sized
109 {
110 response.divisions
111 }
112
113 #[cfg(feature = "cache")]
114 fn get_cache_table() -> &'static RwLock<CacheTable<Self>>
115 where
116 Self: Sized
117 {
118 &CACHE
119 }
120}
121
122entrypoint!(DivisionId => Division);
123entrypoint!(NamedDivision.id => Division);
124entrypoint!(Division.id => Division);
125
126#[cfg(test)]
127mod tests {
128 use crate::divisions::DivisionsRequest;
129 use crate::request::RequestURLBuilderExt;
130
131 #[tokio::test]
132 async fn all_divisions_this_season() {
133 let _response = DivisionsRequest::builder().build_and_get().await.unwrap();
134 }
135}