brasilapi_client/definitions/
holidays.rs1use crate::{client::*, constants::holidays::{SVC_URL,MIN_YEAR, MAX_YEAR}, errors::*, request::*};
2use serde::{Deserialize, Serialize};
3
4mod serde_naivedate {
6 use serde::{self, Deserialize, Serializer, Deserializer};
7
8 const FORMAT: &'static str = "%Y-%m-%d";
9
10 pub fn serialize<S>(
11 date: &chrono::NaiveDate,
12 serializer: S,
13 ) -> Result<S::Ok, S::Error>
14 where
15 S: Serializer,
16 {
17 let s = format!("{}", date.format(FORMAT));
18 serializer.serialize_str(&s)
19 }
20
21 pub fn deserialize<'de, D>(
22 deserializer: D,
23 ) -> Result<chrono::NaiveDate, D::Error>
24 where
25 D: Deserializer<'de>,
26 {
27 let s = String::deserialize(deserializer)?;
28 chrono::NaiveDate::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
29 }
30}
31
32#[derive(Serialize, Deserialize, Debug)]
33#[serde(rename_all = "camelCase")]
34pub struct HolidaysResponseData {
38 #[serde(with = "serde_naivedate")]
40 pub date : chrono::NaiveDate,
41 pub name: String,
43 pub r#type : String
45}
46
47impl PartialEq for HolidaysResponseData {
48
49 fn eq(&self, other: &Self) -> bool {
50 self.date == other.date && self.name == other.name && self.r#type == other.r#type
51 }
52}
53
54impl BrasilApiClient {
55 pub async fn get_holidays(&self, year: &i32) -> Result<Vec<HolidaysResponseData>, Error> {
56 if year < MIN_YEAR || year > MAX_YEAR {
57 return Err(Error::InvalidInputRangeError
58 {
59 name: "year".to_string(),
60 min: *MIN_YEAR,
61 max: *MAX_YEAR
62 })
63 }
64
65
66 Ok(get::<(), Vec<HolidaysResponseData>>(
67 &format!("{}/{}/{}", self.base_url, SVC_URL, year)
68 ).await?)
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::{holidays::{HolidaysResponseData}, client::tests::cli};
75
76 use super::*;
77 use futures_await_test::async_test;
78
79 #[async_test]
80 async fn test_invalid_min_range() {
81 let year = MIN_YEAR - 1;
82 let resp = cli().get_holidays(&year).await;
83 assert!(resp.is_err());
84 }
85
86 #[async_test]
87 async fn test_invalid_max_range() {
88 let year = MAX_YEAR + 1;
89 let resp = cli().get_holidays(&year).await;
90 assert!(resp.is_err());
91 }
92
93 #[async_test]
94 async fn test_valid_at_1900() {
95 let year = MIN_YEAR;
96 let resp = cli().get_holidays(year).await;
97 assert!(resp.is_ok());
98
99 let expected_resp = r#"[{"date":"1900-01-01","name":"Confraternização mundial","type":"national"},{"date":"1900-02-27","name":"Carnaval","type":"national"},{"date":"1900-04-15","name":"Páscoa","type":"national"},{"date":"1900-04-21","name":"Tiradentes","type":"national"},{"date":"1900-05-01","name":"Dia do trabalho","type":"national"},{"date":"1900-06-14","name":"Corpus Christi","type":"national"},{"date":"1900-09-07","name":"Independência do Brasil","type":"national"},{"date":"1900-10-12","name":"Nossa Senhora Aparecida","type":"national"},{"date":"1900-11-02","name":"Finados","type":"national"},{"date":"1900-11-15","name":"Proclamação da República","type":"national"},{"date":"1900-12-25","name":"Natal","type":"national"}]"#;
100 let expected = serde_json::from_str::<Vec<HolidaysResponseData>>(expected_resp).unwrap();
101 let received = resp.unwrap();
102 assert_eq!(expected.len(), received.len());
103
104 let difference:bool = received.iter().any(|item| !expected.contains(item));
105 assert!(!difference);
106 }
107}