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