mlb_api/requests/person/
free_agents.rs1use 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}