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