jquants_api_client/api/
trading_calendar.rs1use serde::{Deserialize, Serialize};
4
5use super::{
6 shared::{traits::builder::JQuantsBuilder, types::holiday_division::HolidayDivision},
7 JQuantsApiClient, JQuantsPlanClient,
8};
9
10#[derive(Clone, Serialize)]
12pub struct TradingCalendarBuilder {
13 #[serde(skip)]
14 client: JQuantsApiClient,
15
16 #[serde(skip_serializing_if = "Option::is_none", rename = "holidaydivision")]
18 holiday_division: Option<HolidayDivision>,
19 #[serde(skip_serializing_if = "Option::is_none")]
21 from: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 to: Option<String>,
25}
26
27impl JQuantsBuilder<TradingCalendarResponse> for TradingCalendarBuilder {
28 async fn send(self) -> Result<TradingCalendarResponse, crate::JQuantsError> {
29 self.send_ref().await
30 }
31
32 async fn send_ref(&self) -> Result<TradingCalendarResponse, crate::JQuantsError> {
33 self.client
34 .inner
35 .get("markets/trading_calendar", self)
36 .await
37 }
38}
39
40impl TradingCalendarBuilder {
41 pub(crate) fn new(client: JQuantsApiClient) -> Self {
43 Self {
44 client,
45 holiday_division: None,
46 from: None,
47 to: None,
48 }
49 }
50
51 pub fn holiday_division(mut self, holiday_division: impl Into<HolidayDivision>) -> Self {
53 self.holiday_division = Some(holiday_division.into());
54 self
55 }
56
57 pub fn from(mut self, from: impl Into<String>) -> Self {
59 self.from = Some(from.into());
60 self
61 }
62
63 pub fn to(mut self, to: impl Into<String>) -> Self {
65 self.to = Some(to.into());
66 self
67 }
68}
69
70pub trait TradingCalendarApi: JQuantsPlanClient {
72 fn get_trading_calendar(&self) -> TradingCalendarBuilder {
76 TradingCalendarBuilder::new(self.get_api_client().clone())
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Deserialize)]
84pub struct TradingCalendarResponse {
85 pub trading_calendar: Vec<TradingCalendarItem>,
87}
88
89#[derive(Debug, Clone, PartialEq, Deserialize)]
91pub struct TradingCalendarItem {
92 #[serde(rename = "Date")]
94 pub date: String,
95
96 #[serde(rename = "HolidayDivision")]
98 pub holiday_division: HolidayDivision,
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn test_deserialize_trading_calendar_response() {
107 let json = r#"
108 {
109 "trading_calendar": [
110 {
111 "Date": "2015-04-01",
112 "HolidayDivision": "1"
113 }
114 ]
115 }
116 "#;
117
118 let response: TradingCalendarResponse = serde_json::from_str(json).unwrap();
119 let expected_response = TradingCalendarResponse {
120 trading_calendar: vec![TradingCalendarItem {
121 date: "2015-04-01".to_string(),
122 holiday_division: HolidayDivision::BusinessDay,
123 }],
124 };
125
126 pretty_assertions::assert_eq!(response, expected_response);
127 }
128
129 #[test]
130 fn test_deserialize_trading_calendar_response_multiple_items() {
131 let json = r#"
132 {
133 "trading_calendar": [
134 {
135 "Date": "2015-03-25",
136 "HolidayDivision": "2"
137 },
138 {
139 "Date": "2015-04-01",
140 "HolidayDivision": "1"
141 }
142 ]
143 }
144 "#;
145
146 let response: TradingCalendarResponse = serde_json::from_str(json).unwrap();
147 let expected_response = TradingCalendarResponse {
148 trading_calendar: vec![
149 TradingCalendarItem {
150 date: "2015-03-25".to_string(),
151 holiday_division: HolidayDivision::HalfDayTrading,
152 },
153 TradingCalendarItem {
154 date: "2015-04-01".to_string(),
155 holiday_division: HolidayDivision::BusinessDay,
156 },
157 ],
158 };
159
160 pretty_assertions::assert_eq!(response, expected_response);
161 }
162
163 #[test]
164 fn test_deserialize_trading_calendar_response_no_data() {
165 let json = r#"
166 {
167 "trading_calendar": []
168 }
169 "#;
170
171 let response: TradingCalendarResponse = serde_json::from_str(json).unwrap();
172 let expected_response = TradingCalendarResponse {
173 trading_calendar: vec![],
174 };
175
176 pretty_assertions::assert_eq!(response, expected_response);
177 }
178}