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