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