Skip to main content

mlb_api/requests/meta/
positions.rs

1use std::hash::{Hash, Hasher};
2use derive_more::{Deref, DerefMut};
3use serde::Deserialize;
4
5id!(#[doc = "A [`String`] representing a position on the field, such as Pitcher, 1st Baseman, etc. These values use 1-9, so Pitcher = \"1\", etc."] PositionCode { code: String });
6
7/// A [`Position`] with a name.
8///
9/// ## Examples
10/// ```
11/// NamedPosition {
12///     code: "3".into(),
13///     name: "First Base".into(),
14///     r#type: "Infielder".into(),
15///     abbreviation: "1B".into(),
16/// }
17/// ```
18#[derive(Debug, Deserialize, Clone, Eq)]
19#[serde(rename_all = "camelCase")]
20pub struct NamedPosition {
21	pub code: PositionCode,
22	#[serde(alias = "displayName")]
23	pub name: String,
24	#[serde(rename = "type")]
25	pub r#type: String,
26	#[serde(alias = "abbrev")]
27	pub abbreviation: String,
28}
29
30impl Hash for NamedPosition {
31	fn hash<H: Hasher>(&self, state: &mut H) {
32		self.code.hash(state);
33	}
34}
35
36impl NamedPosition {
37	#[must_use]
38	pub fn unknown_position() -> Self {
39		Self {
40			code: PositionCode::new("X"),
41			name: "Unknown".to_owned(),
42			r#type: "Unknown".to_owned(),
43			abbreviation: "X".to_owned(),
44		}
45	}
46}
47
48/// A Position with every piece of data you could describe about it.
49///
50/// ## Examples
51/// ```
52/// Position {
53///     short_name: "1st Base".into(),
54///     full_name: "First Base".into(),
55///     abbreviation: "1B".into(),
56///     code: "3".into(),
57///     r#type: "Infielder".into(),
58///     formal_name: "First Baseman".into(),
59///     name: "First Base".into(),
60///     is_pitcher: false,
61///     is_game_position: true,
62///     is_fielder: true,
63///     is_outfield: false,
64/// }
65/// ```
66#[allow(clippy::struct_excessive_bools, reason = "false positive")]
67#[derive(Debug, Deserialize, Deref, DerefMut, Clone)]
68#[serde(rename_all = "camelCase")]
69pub struct Position {
70	pub short_name: String,
71	pub full_name: String,
72	pub formal_name: String,
73	#[serde(rename = "pitcher")]
74	pub is_pitcher: bool,
75	#[serde(rename = "gamePosition")]
76	pub is_game_position: bool,
77	#[serde(rename = "fielder")]
78	pub is_fielder: bool,
79	#[serde(rename = "outfield")]
80	pub is_outfield: bool,
81
82	#[deref]
83	#[deref_mut]
84	#[serde(flatten)]
85	inner: NamedPosition,
86}
87
88impl Hash for Position {
89	fn hash<H: Hasher>(&self, state: &mut H) {
90		self.code.hash(state);
91	}
92}
93
94impl Position {
95	#[must_use]
96	pub fn unknown_position() -> Self {
97		Self {
98			short_name: "Unknown".to_owned(),
99			full_name: "Unknown".to_owned(),
100			formal_name: "Unknown".to_owned(),
101			is_pitcher: false,
102			is_game_position: false,
103			is_fielder: false,
104			is_outfield: false,
105			inner: NamedPosition::unknown_position(),
106		}
107	}
108}
109
110id_only_eq_impl!(Position, code);
111id_only_eq_impl!(NamedPosition, code);
112meta_kind_impl!("positions" => Position);
113tiered_request_entry_cache_impl!([Position, NamedPosition].code: PositionCode);
114test_impl!(Position);