Skip to main content

mlb_api/requests/meta/
metrics.rs

1use crate::meta::stat_groups::StatGroup;
2use derive_more::{Deref, DerefMut};
3use serde::Deserialize;
4
5id!(MetricId { metricId: u32 });
6
7macro_rules! units {
8    ($($name:ident($func:path => $units:ty)),+ $(,)?) => {
9        #[derive(Debug, ::serde::Deserialize, Clone)]
10        #[serde(try_from = "__UnitStruct")]
11        pub enum Unit {
12            $($name($units),)+
13            Unknown(String),
14        }
15
16		impl PartialEq for Unit {
17			fn eq(&self, other: &Self) -> bool {
18				match (self, other) {
19					// PartialEq trait doesn't exist yet, so we have to use the other stuff implemented here
20					$((Self::$name(lhs), Self::$name(rhs)) => format!("{lhs:?}") == format!("{rhs:?}"),)+
21					(Self::Unknown(lhs), Self::Unknown(rhs)) => lhs == rhs,
22					_ => false,
23				}
24			}
25		}
26
27        impl Eq for Unit {}
28
29        #[derive(::serde::Deserialize)]
30        struct __UnitStruct(String);
31
32        impl TryFrom<__UnitStruct> for Unit {
33            type Error = ::uom::str::ParseQuantityError;
34
35            fn try_from(value: __UnitStruct) -> Result<Self, Self::Error> {
36                let __UnitStruct(inner) = value;
37
38				$(
39				for unit in $func() {
40					let abbreviation = unit.abbreviation();
41					if abbreviation.eq_ignore_ascii_case(&inner) {
42						return Ok(Self::$name(unit));
43					}
44				}
45				)+
46
47                Ok(Self::Unknown(inner))
48            }
49        }
50    };
51}
52
53units! {
54	AngularVelocity(uom::si::angular_velocity::units => uom::si::angular_velocity::Units),
55	Length(uom::si::length::units => uom::si::length::Units),
56	Velocity(uom::si::velocity::units => uom::si::velocity::Units),
57	Angle(uom::si::angle::units => uom::si::angle::Units),
58	Time(uom::si::time::units => uom::si::time::Units),
59}
60
61#[derive(Debug, Deserialize, Clone)]
62#[serde(rename_all = "camelCase")]
63pub struct NamedMetric {
64	pub name: String,
65	#[serde(flatten)]
66	pub id: MetricId,
67}
68
69#[derive(Debug, Deserialize, Deref, DerefMut, Clone)]
70#[serde(rename_all = "camelCase")]
71pub struct Metric {
72	#[serde(default)]
73	#[serde(rename = "group", deserialize_with = "crate::types::deserialize_comma_separated_vec")]
74	pub groups: Vec<StatGroup>,
75	pub unit: Option<Unit>,
76
77	#[deref]
78	#[deref_mut]
79	#[serde(flatten)]
80	inner: NamedMetric,
81}
82
83id_only_eq_impl!(NamedMetric, id);
84id_only_eq_impl!(Metric, id);
85meta_kind_impl!("metrics" => Metric);
86tiered_request_entry_cache_impl!([Metric, NamedMetric].id: MetricId);
87test_impl!(Metric);