Skip to main content

mlb_api/requests/person/
free_agents.rs

1use crate::season::SeasonId;
2use crate::types::Copyright;
3use bon::Builder;
4use chrono::NaiveDate;
5use serde::Deserialize;
6use serde_with::serde_as;
7use serde_with::DefaultOnError;
8use std::fmt::{Display, Formatter};
9use crate::person::NamedPerson;
10use crate::positions::NamedPosition;
11use crate::request::RequestURL;
12use crate::team::NamedTeam;
13
14#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
15#[serde(rename_all = "camelCase")]
16pub struct FreeAgentsResponse {
17	pub copyright: Copyright,
18	pub free_agents: Vec<FreeAgent>,
19}
20
21#[serde_as]
22#[derive(Deserialize)]
23#[serde(rename_all = "camelCase")]
24#[doc(hidden)]
25struct __FreeAgentStruct {
26	player: NamedPerson,
27	#[serde_as(deserialize_as = "DefaultOnError")]
28	original_team: Option<NamedTeam>,
29	#[serde_as(deserialize_as = "DefaultOnError")]
30	new_team: Option<NamedTeam>,
31	notes: Option<String>,
32	date_signed: Option<NaiveDate>,
33	date_declared: Option<NaiveDate>,
34	position: NamedPosition,
35}
36
37#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
38#[serde(from = "__FreeAgentStruct")]
39pub struct FreeAgent {
40	pub player: NamedPerson,
41	pub original_team: NamedTeam,
42	pub new_team: NamedTeam,
43	pub notes: Option<String>,
44	pub date_signed: NaiveDate,
45	pub date_declared: NaiveDate,
46	pub position: NamedPosition,
47}
48
49impl From<__FreeAgentStruct> for FreeAgent {
50	fn from(value: __FreeAgentStruct) -> Self {
51		Self {
52			player: value.player,
53			original_team: value.original_team.unwrap_or_else(NamedTeam::unknown_team),
54			new_team: value.new_team.unwrap_or_else(NamedTeam::unknown_team),
55			notes: value.notes,
56			date_signed: value.date_signed.or(value.date_declared).unwrap_or_default(),
57			date_declared: value.date_declared.or(value.date_signed).unwrap_or_default(),
58			position: value.position,
59		}
60	}
61}
62
63#[derive(Builder)]
64#[builder(derive(Into))]
65pub struct FreeAgentsRequest {
66	#[builder(into)]
67	season: SeasonId,
68}
69
70impl<S: free_agents_request_builder::State + free_agents_request_builder::IsComplete> crate::request::RequestURLBuilderExt for FreeAgentsRequestBuilder<S> {
71	type Built = FreeAgentsRequest;
72}
73
74impl Display for FreeAgentsRequest {
75	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
76		write!(f, "http://statsapi.mlb.com/api/v1/people/freeAgents{}", gen_params! { "season": self.season })
77	}
78}
79
80impl RequestURL for FreeAgentsRequest {
81	type Response = FreeAgentsResponse;
82}
83
84#[cfg(test)]
85mod tests {
86	use crate::request::RequestURLBuilderExt;
87	use crate::person::free_agents::FreeAgentsRequest;
88	use crate::TEST_YEAR;
89
90	#[tokio::test]
91	async fn test_one_year() {
92		let _response = FreeAgentsRequest::builder().season(TEST_YEAR).build_and_get().await.unwrap();
93	}
94
95	#[tokio::test]
96	async fn test_all_seasons() {
97		for season in 2001..=TEST_YEAR {
98			let _response = FreeAgentsRequest::builder().season(season).build_and_get().await.unwrap();
99		}
100	}
101}