1use const_format::formatcp;
4use jiff::civil::Date;
5use serde::Serialize;
6
7use crate::{
8 API_BASE_URL, Client, parser,
9 parser::parse_none,
10 types::{
11 error::NoEndpointSpecificError,
12 params::{
13 Aggregation, GetExtendedParams, GetInsolationParams, GetOutputParams, GetOutputParamsOuter, GetStatisticsParams,
14 GetStatusParams, GetStatusParamsOuter, GetSystemParams,
15 },
16 regions::Region,
17 response::{
18 AggregatedOutput, DailyStatus, ExtendedData, FavouriteSystem, FullSystem, History, Insolation, Ladder, Output,
19 Response, Statistics, Status, Supply, Team, TeamOutput,
20 },
21 },
22};
23
24impl Client {
25 pub async fn get_status(&self, params: GetStatusParams) -> crate::Result<Response<Status>, NoEndpointSpecificError> {
32 self
33 .get_single(
34 formatcp!("{API_BASE_URL}/getstatus.jsp"),
35 GetStatusParamsOuter::new(params, false, false),
36 parse_none,
37 )
38 .await
39 }
40
41 pub async fn get_status_history(
48 &self,
49 params: GetStatusParams,
50 ) -> crate::Result<Response<Vec<History>>, NoEndpointSpecificError> {
51 self
52 .get_multiple(
53 formatcp!("{API_BASE_URL}/getstatus.jsp"),
54 GetStatusParamsOuter::new(params, true, false),
55 parse_none,
56 )
57 .await
58 }
59
60 pub async fn get_status_daily(
67 &self,
68 params: GetStatusParams,
69 ) -> crate::Result<Response<DailyStatus>, NoEndpointSpecificError> {
70 let (rate_limit, response) = self
71 .get(
72 formatcp!("{API_BASE_URL}/getstatus.jsp"),
73 GetStatusParamsOuter::new(params, false, true),
74 parse_none,
75 )
76 .await?;
77
78 Ok(Response::new(parser::daily_status(&response)?, rate_limit))
79 }
80
81 pub async fn get_statistics(
91 &self,
92 params: GetStatisticsParams,
93 ) -> crate::Result<Response<Statistics>, NoEndpointSpecificError> {
94 let (rate_limit, response) = self.get(formatcp!("{API_BASE_URL}/getstatistic.jsp"), ¶ms, parse_none).await?;
95
96 Ok(Response::new(parser::statistics(&response, ¶ms)?, rate_limit))
97 }
98
99 pub async fn get_system(
103 &self,
104 params: GetSystemParams,
105 ) -> crate::Result<Response<FullSystem>, NoEndpointSpecificError> {
106 let (rate_limit, response) = self.get(formatcp!("{API_BASE_URL}/getsystem.jsp"), ¶ms, parse_none).await?;
107
108 Ok(Response::new(parser::system(&response, ¶ms)?, rate_limit))
109 }
110
111 pub async fn get_ladder(&self, system: Option<u32>) -> crate::Result<Response<Ladder>, NoEndpointSpecificError> {
120 self.get_single(formatcp!("{API_BASE_URL}/getladder.jsp"), &[("sid1", system)], parse_none).await
121 }
122
123 pub async fn get_outputs(
130 &self,
131 params: GetOutputParams,
132 ) -> crate::Result<Response<Vec<Output>>, NoEndpointSpecificError> {
133 let params = GetOutputParamsOuter {
134 params,
135 ..Default::default()
136 };
137
138 let (rate_limit, response) = self.get(formatcp!("{API_BASE_URL}/getoutput.jsp"), ¶ms, parse_none).await?;
139 Ok(Response::new(parser::outputs(&response, ¶ms.params)?, rate_limit))
140 }
141
142 pub async fn get_aggregate_outputs(
149 &self,
150 aggregation: Aggregation,
151 params: GetOutputParams,
152 ) -> crate::Result<Response<Vec<AggregatedOutput>>, NoEndpointSpecificError> {
153 let params = GetOutputParamsOuter {
154 params,
155 a: Some(aggregation),
156 ..Default::default()
157 };
158
159 let (rate_limit, response) = self.get(formatcp!("{API_BASE_URL}/getoutput.jsp"), ¶ms, parse_none).await?;
160 Ok(Response::new(parser::aggregate_outputs(&response, params.params.time_of_export)?, rate_limit))
161 }
162
163 pub async fn get_team_outputs(
170 &self,
171 team_id: u32,
172 params: GetOutputParams,
173 ) -> crate::Result<Response<Vec<TeamOutput>>, NoEndpointSpecificError> {
174 self
175 .get_multiple(
176 formatcp!("{API_BASE_URL}/getoutput.jsp"),
177 GetOutputParamsOuter {
178 params,
179 tid: Some(team_id),
180 ..Default::default()
181 },
182 parse_none,
183 )
184 .await
185 }
186
187 pub async fn get_extended(
197 &self,
198 params: GetExtendedParams,
199 ) -> crate::Result<Response<Vec<ExtendedData>>, NoEndpointSpecificError> {
200 self.get_multiple(formatcp!("{API_BASE_URL}/getextended.jsp"), ¶ms, parse_none).await
201 }
202
203 pub async fn get_favourites(
213 &self,
214 system: Option<u32>,
215 ) -> crate::Result<Response<Vec<FavouriteSystem>>, NoEndpointSpecificError> {
216 let (rate_limit, response) =
217 self.get(formatcp!("{API_BASE_URL}/getfavourite.jsp"), &[("sid1", system)], parse_none).await?;
218 Ok(Response::new(parser::favourites(&response)?, rate_limit))
219 }
220
221 pub async fn get_missing(
227 &self,
228 from: Option<Date>,
229 to: Option<Date>,
230 ) -> crate::Result<Response<Vec<Date>>, NoEndpointSpecificError> {
231 self
232 .get_single(
233 formatcp!("{API_BASE_URL}/getmissing.jsp"),
234 &[
235 ("df", from.map(|d| d.strftime("%Y%m%d").to_string())),
236 ("dt", to.map(|d| d.strftime("%Y%m%d").to_string())),
237 ],
238 parse_none,
239 )
240 .await
241 }
242
243 pub async fn get_insolation(
249 &self,
250 params: GetInsolationParams,
251 ) -> crate::Result<Response<Vec<Insolation>>, NoEndpointSpecificError> {
252 self.get_multiple(formatcp!("{API_BASE_URL}/getinsolation.jsp"), ¶ms, parse_none).await
253 }
254
255 pub async fn get_team(&self, team: u32) -> crate::Result<Response<Team>, NoEndpointSpecificError> {
262 let (rate_limit, response) =
264 self.get(formatcp!("{API_BASE_URL}/getteam.jsp"), &[("tid", team)], parse_none).await?;
265
266 Ok(Response::new(
267 Self::semicolon_reader(&response).deserialize().collect::<csv::Result<Vec<_>>>()?.remove(0),
268 rate_limit,
269 ))
270 }
271
272 pub async fn get_supply(
283 &self,
284 region: Option<Region>,
285 timezone: Option<String>,
286 ) -> crate::Result<Response<Vec<Supply>>, NoEndpointSpecificError> {
287 #[derive(Serialize)]
288 struct Params {
289 r: Option<Region>,
290 tz: Option<String>,
291 }
292
293 let params = Params {
294 r: region,
295 tz: timezone,
296 };
297 self.get_multiple(formatcp!("{API_BASE_URL}/getsupply.jsp"), ¶ms, parse_none).await
298 }
299}