1#![allow(
3 clippy::doc_markdown,
4 clippy::missing_errors_doc,
5 clippy::must_use_candidate,
6 clippy::needless_pass_by_value,
7 clippy::return_self_not_must_use,
8 clippy::single_match_else
9)]
10
11use std::fmt;
12#[derive(Debug, Clone, PartialEq)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub struct PsiResponse {
15 pub code: NeaSuccessCode,
17 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
19 pub error_msg: String,
20 pub data: PsiData,
21}
22#[derive(Debug, Clone, PartialEq)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24pub struct Pm25Response {
25 pub code: NeaSuccessCode,
27 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
29 pub error_msg: String,
30 pub data: Pm25Data,
31}
32#[derive(Debug, Clone, PartialEq)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub struct AirTemperatureResponse {
35 pub code: NeaSuccessCode,
37 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
39 pub error_msg: String,
40 pub data: AirTemperatureData,
41}
42#[derive(Debug, Clone, PartialEq)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44pub struct RelativeHumidityResponse {
45 pub code: NeaSuccessCode,
47 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
49 pub error_msg: String,
50 pub data: RelativeHumidityData,
51}
52#[derive(Debug, Clone, PartialEq)]
53#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54pub struct WindSpeedResponse {
55 pub code: NeaSuccessCode,
57 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
59 pub error_msg: String,
60 pub data: WindSpeedData,
61}
62#[derive(Debug, Clone, PartialEq)]
63#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64pub struct WindDirectionResponse {
65 pub code: NeaSuccessCode,
67 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
69 pub error_msg: String,
70 pub data: WindDirectionData,
71}
72#[derive(Debug, Clone, PartialEq)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
74pub struct RainfallResponse {
75 pub code: NeaSuccessCode,
77 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
79 pub error_msg: String,
80 pub data: RainfallData,
81}
82#[derive(Debug, Clone, PartialEq)]
83#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
84pub struct TwoHrForecastResponse {
85 pub code: NeaSuccessCode,
87 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
89 pub error_msg: String,
90 pub data: TwoHrForecastData,
91}
92#[derive(Debug, Clone, PartialEq)]
93#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
94pub struct TwentyFourHrForecastResponse {
95 pub code: NeaSuccessCode,
97 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
99 pub error_msg: String,
100 pub data: TwentyFourHrForecastData,
101}
102#[derive(Debug, Clone, PartialEq)]
103#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
104pub struct FourDayOutlookResponse {
105 pub code: NeaSuccessCode,
107 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
109 pub error_msg: String,
110 pub data: FourDayOutlookData,
112}
113#[derive(Debug, Clone, PartialEq)]
114#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
115pub struct UvResponse {
116 pub code: NeaSuccessCode,
118 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
120 pub error_msg: String,
121 pub data: UvData,
122}
123#[derive(Debug, Clone, PartialEq)]
124#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
125pub struct WeatherSubApiResponse {
126 #[cfg_attr(
128 feature = "serde",
129 serde(default, skip_serializing_if = "Option::is_none")
130 )]
131 pub code: Option<NeaSuccessCode>,
132 #[cfg_attr(
134 feature = "serde",
135 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
136 )]
137 pub error_msg: Option<String>,
138 #[cfg_attr(
139 feature = "serde",
140 serde(default, skip_serializing_if = "Option::is_none")
141 )]
142 pub data: Option<WeatherSubApiData>,
143}
144#[derive(Debug, Clone, PartialEq)]
145#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
146pub struct InvalidParamsError {
147 #[cfg_attr(
148 feature = "serde",
149 serde(default, skip_serializing_if = "Option::is_none")
150 )]
151 pub code: Option<f64>,
152 #[cfg_attr(
153 feature = "serde",
154 serde(default, skip_serializing_if = "Option::is_none")
155 )]
156 pub name: Option<String>,
157 #[cfg_attr(
159 feature = "serde",
160 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
161 )]
162 pub error_msg: Option<NeaInvalidParamsErrorMsg>,
163}
164#[derive(Debug, Clone, PartialEq)]
165#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
166pub struct InvalidParamsError22 {
167 #[cfg_attr(
168 feature = "serde",
169 serde(default, skip_serializing_if = "Option::is_none")
170 )]
171 pub code: Option<f64>,
172 #[cfg_attr(
173 feature = "serde",
174 serde(default, skip_serializing_if = "Option::is_none")
175 )]
176 pub name: Option<String>,
177 #[cfg_attr(
178 feature = "serde",
179 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
180 )]
181 pub error_msg: Option<String>,
182}
183#[derive(Debug, Clone, PartialEq)]
184#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
185pub struct DataNotFoundError {
186 #[cfg_attr(
187 feature = "serde",
188 serde(default, skip_serializing_if = "Option::is_none")
189 )]
190 pub code: Option<f64>,
191 #[cfg_attr(
192 feature = "serde",
193 serde(default, skip_serializing_if = "Option::is_none")
194 )]
195 pub name: Option<String>,
196 #[cfg_attr(
197 feature = "serde",
198 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
199 )]
200 pub error_msg: Option<String>,
201}
202#[derive(Debug, Clone, PartialEq)]
203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
204pub struct RateLimitError {
205 #[cfg_attr(
206 feature = "serde",
207 serde(default, skip_serializing_if = "Option::is_none")
208 )]
209 pub code: Option<f64>,
210 #[cfg_attr(
211 feature = "serde",
212 serde(default, skip_serializing_if = "Option::is_none")
213 )]
214 pub name: Option<String>,
215 #[cfg_attr(
216 feature = "serde",
217 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
218 )]
219 pub error_msg: Option<String>,
220}
221#[derive(Debug, Clone, PartialEq)]
222#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
223pub struct MissingAuthResponse {
224 #[cfg_attr(
225 feature = "serde",
226 serde(default, skip_serializing_if = "Option::is_none")
227 )]
228 pub message: Option<String>,
229}
230#[nutype::nutype(
232 validate(less_or_equal = 0),
233 derive(
234 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
235 ),
236 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
237)]
238pub struct NeaSuccessCode(u8);
239pub type NeaOffsetDateTime = satay_runtime::OffsetDateTime;
241pub type NeaDate = satay_runtime::Date;
243#[nutype::nutype(
245 validate(finite, greater_or_equal = 1.0, less_or_equal = 1.5),
246 derive(
247 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
248 ),
249 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
250)]
251pub struct NeaLatitude(f64);
252#[nutype::nutype(
254 validate(finite, greater_or_equal = 103.5, less_or_equal = 104.2),
255 derive(
256 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
257 ),
258 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
259)]
260pub struct NeaLongitude(f64);
261#[nutype::nutype(
263 validate(less_or_equal = 500),
264 derive(
265 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
266 ),
267 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
268)]
269pub struct NeaRegionalReading(u16);
270#[nutype::nutype(
272 validate(less_or_equal = 500),
273 derive(
274 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
275 ),
276 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
277)]
278pub struct NeaPm25HourlyReading(u16);
279#[nutype::nutype(
281 validate(less_or_equal = 360),
282 derive(
283 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
284 ),
285 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
286)]
287pub struct NeaWindDirectionDegrees(u16);
288#[nutype::nutype(
290 validate(less_or_equal = 16),
291 derive(
292 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
293 ),
294 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
295)]
296pub struct NeaUvIndex(u8);
297#[nutype::nutype(
299 validate(finite, greater_or_equal = 0.0, less_or_equal = 100.0),
300 derive(
301 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
302 ),
303 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
304)]
305pub struct NeaHumidityPercent(f64);
306#[nutype::nutype(
308 validate(finite, greater_or_equal = 15.0, less_or_equal = 45.0),
309 derive(
310 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
311 ),
312 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
313)]
314pub struct NeaTemperatureCelsius(f64);
315#[nutype::nutype(
317 validate(finite, greater_or_equal = 0.0, less_or_equal = 120.0),
318 derive(
319 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
320 ),
321 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
322)]
323pub struct NeaWindSpeedKmh(f64);
324#[derive(Debug, Clone, PartialEq, Eq)]
326#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
327pub enum NeaForecastCode {
328 #[cfg_attr(feature = "serde", serde(rename = "FA"))]
329 FairDay,
330 #[cfg_attr(feature = "serde", serde(rename = "FN"))]
331 FairNight,
332 #[cfg_attr(feature = "serde", serde(rename = "FW"))]
333 FairAndWarm,
334 #[cfg_attr(feature = "serde", serde(rename = "CL"))]
335 Cloudy,
336 #[cfg_attr(feature = "serde", serde(rename = "PC"))]
337 PartlyCloudyDay,
338 #[cfg_attr(feature = "serde", serde(rename = "PN"))]
339 PartlyCloudyNight,
340 #[cfg_attr(feature = "serde", serde(rename = "HZ"))]
341 Hazy,
342 #[cfg_attr(feature = "serde", serde(rename = "SH"))]
343 SlightlyHazy,
344 #[cfg_attr(feature = "serde", serde(rename = "MS"))]
345 Mist,
346 #[cfg_attr(feature = "serde", serde(rename = "FG"))]
347 Fog,
348 #[cfg_attr(feature = "serde", serde(rename = "LR"))]
349 LightRain,
350 #[cfg_attr(feature = "serde", serde(rename = "MR"))]
351 ModerateRain,
352 #[cfg_attr(feature = "serde", serde(rename = "HR"))]
353 HeavyRain,
354 #[cfg_attr(feature = "serde", serde(rename = "PS"))]
355 PassingShowers,
356 #[cfg_attr(feature = "serde", serde(rename = "LS"))]
357 LightShowers,
358 #[cfg_attr(feature = "serde", serde(rename = "HS"))]
359 HeavyShowers,
360 #[cfg_attr(feature = "serde", serde(rename = "HT"))]
361 HeavyThunderyShowers,
362 #[cfg_attr(feature = "serde", serde(rename = "HG"))]
363 HeavyThunderyShowersWithGustyWinds,
364 #[cfg_attr(feature = "serde", serde(rename = "TL"))]
365 ThunderyShowers,
366 #[cfg_attr(feature = "serde", serde(rename = "WD"))]
367 Windy,
368}
369impl NeaForecastCode {
370 pub const fn as_str(&self) -> &'static str {
371 match self {
372 Self::FairDay => "FA",
373 Self::FairNight => "FN",
374 Self::FairAndWarm => "FW",
375 Self::Cloudy => "CL",
376 Self::PartlyCloudyDay => "PC",
377 Self::PartlyCloudyNight => "PN",
378 Self::Hazy => "HZ",
379 Self::SlightlyHazy => "SH",
380 Self::Mist => "MS",
381 Self::Fog => "FG",
382 Self::LightRain => "LR",
383 Self::ModerateRain => "MR",
384 Self::HeavyRain => "HR",
385 Self::PassingShowers => "PS",
386 Self::LightShowers => "LS",
387 Self::HeavyShowers => "HS",
388 Self::HeavyThunderyShowers => "HT",
389 Self::HeavyThunderyShowersWithGustyWinds => "HG",
390 Self::ThunderyShowers => "TL",
391 Self::Windy => "WD",
392 }
393 }
394}
395impl AsRef<str> for NeaForecastCode {
396 fn as_ref(&self) -> &str {
397 self.as_str()
398 }
399}
400impl fmt::Display for NeaForecastCode {
401 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402 f.write_str(self.as_str())
403 }
404}
405#[derive(Debug, Clone, PartialEq, Eq)]
407#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
408pub enum NeaLightningType {
409 #[cfg_attr(feature = "serde", serde(rename = "C"))]
410 CloudToCloud,
411 #[cfg_attr(feature = "serde", serde(rename = "G"))]
412 CloudToGround,
413}
414impl NeaLightningType {
415 pub const fn as_str(&self) -> &'static str {
416 match self {
417 Self::CloudToCloud => "C",
418 Self::CloudToGround => "G",
419 }
420 }
421}
422impl AsRef<str> for NeaLightningType {
423 fn as_ref(&self) -> &str {
424 self.as_str()
425 }
426}
427impl fmt::Display for NeaLightningType {
428 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
429 f.write_str(self.as_str())
430 }
431}
432#[derive(Debug, Clone, PartialEq, Eq)]
434#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
435pub enum NeaForecastText {
436 Fair,
437 #[cfg_attr(feature = "serde", serde(rename = "Fair (Day)"))]
438 FairDay,
439 #[cfg_attr(feature = "serde", serde(rename = "Fair (Night)"))]
440 FairNight,
441 #[cfg_attr(feature = "serde", serde(rename = "Fair & Warm"))]
442 FairAndWarm,
443 #[cfg_attr(feature = "serde", serde(rename = "Partly Cloudy"))]
444 PartlyCloudy,
445 #[cfg_attr(feature = "serde", serde(rename = "Partly Cloudy (Day)"))]
446 PartlyCloudyDay,
447 #[cfg_attr(feature = "serde", serde(rename = "Partly Cloudy (Night)"))]
448 PartlyCloudyNight,
449 Cloudy,
450 Hazy,
451 #[cfg_attr(feature = "serde", serde(rename = "Slightly Hazy"))]
452 SlightlyHazy,
453 Windy,
454 Mist,
455 Fog,
456 #[cfg_attr(feature = "serde", serde(rename = "Light Rain"))]
457 LightRain,
458 #[cfg_attr(feature = "serde", serde(rename = "Moderate Rain"))]
459 ModerateRain,
460 #[cfg_attr(feature = "serde", serde(rename = "Heavy Rain"))]
461 HeavyRain,
462 #[cfg_attr(feature = "serde", serde(rename = "Passing Showers"))]
463 PassingShowers,
464 #[cfg_attr(feature = "serde", serde(rename = "Light Showers"))]
465 LightShowers,
466 Showers,
467 #[cfg_attr(feature = "serde", serde(rename = "Heavy Showers"))]
468 HeavyShowers,
469 #[cfg_attr(feature = "serde", serde(rename = "Thundery Showers"))]
470 ThunderyShowers,
471 #[cfg_attr(feature = "serde", serde(rename = "Heavy Thundery Showers"))]
472 HeavyThunderyShowers,
473 #[cfg_attr(
474 feature = "serde",
475 serde(rename = "Heavy Thundery Showers with Gusty Winds")
476 )]
477 HeavyThunderyShowersWithGustyWinds,
478}
479impl NeaForecastText {
480 pub const fn as_str(&self) -> &'static str {
481 match self {
482 Self::Fair => "Fair",
483 Self::FairDay => "Fair (Day)",
484 Self::FairNight => "Fair (Night)",
485 Self::FairAndWarm => "Fair & Warm",
486 Self::PartlyCloudy => "Partly Cloudy",
487 Self::PartlyCloudyDay => "Partly Cloudy (Day)",
488 Self::PartlyCloudyNight => "Partly Cloudy (Night)",
489 Self::Cloudy => "Cloudy",
490 Self::Hazy => "Hazy",
491 Self::SlightlyHazy => "Slightly Hazy",
492 Self::Windy => "Windy",
493 Self::Mist => "Mist",
494 Self::Fog => "Fog",
495 Self::LightRain => "Light Rain",
496 Self::ModerateRain => "Moderate Rain",
497 Self::HeavyRain => "Heavy Rain",
498 Self::PassingShowers => "Passing Showers",
499 Self::LightShowers => "Light Showers",
500 Self::Showers => "Showers",
501 Self::HeavyShowers => "Heavy Showers",
502 Self::ThunderyShowers => "Thundery Showers",
503 Self::HeavyThunderyShowers => "Heavy Thundery Showers",
504 Self::HeavyThunderyShowersWithGustyWinds => "Heavy Thundery Showers with Gusty Winds",
505 }
506 }
507}
508impl AsRef<str> for NeaForecastText {
509 fn as_ref(&self) -> &str {
510 self.as_str()
511 }
512}
513impl fmt::Display for NeaForecastText {
514 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
515 f.write_str(self.as_str())
516 }
517}
518#[derive(Debug, Clone, PartialEq, Eq)]
520#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
521pub enum NeaDayOfWeek {
522 Monday,
523 Tuesday,
524 Wednesday,
525 Thursday,
526 Friday,
527 Saturday,
528 Sunday,
529}
530impl NeaDayOfWeek {
531 pub const fn as_str(&self) -> &'static str {
532 match self {
533 Self::Monday => "Monday",
534 Self::Tuesday => "Tuesday",
535 Self::Wednesday => "Wednesday",
536 Self::Thursday => "Thursday",
537 Self::Friday => "Friday",
538 Self::Saturday => "Saturday",
539 Self::Sunday => "Sunday",
540 }
541 }
542}
543impl AsRef<str> for NeaDayOfWeek {
544 fn as_ref(&self) -> &str {
545 self.as_str()
546 }
547}
548impl fmt::Display for NeaDayOfWeek {
549 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
550 f.write_str(self.as_str())
551 }
552}
553#[derive(Debug, Clone, PartialEq, Eq)]
555#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
556pub enum NeaInvalidParamsErrorMsg {
557 #[cfg_attr(
558 feature = "serde",
559 serde(
560 rename = "Invalid date format. Date format must be YYYY-MM-DD (2024-06-01) or YYYY-MM-DDTHH:mm:ss (2024-06-01T08:30:00)."
561 )
562 )]
563 InvalidDateFormat,
564 #[cfg_attr(feature = "serde", serde(rename = "Invalid pagination token."))]
565 InvalidPaginationToken,
566}
567impl NeaInvalidParamsErrorMsg {
568 pub const fn as_str(&self) -> &'static str {
569 match self {
570 Self::InvalidDateFormat => {
571 "Invalid date format. Date format must be YYYY-MM-DD (2024-06-01) or YYYY-MM-DDTHH:mm:ss (2024-06-01T08:30:00)."
572 }
573 Self::InvalidPaginationToken => "Invalid pagination token.",
574 }
575 }
576}
577impl AsRef<str> for NeaInvalidParamsErrorMsg {
578 fn as_ref(&self) -> &str {
579 self.as_str()
580 }
581}
582impl fmt::Display for NeaInvalidParamsErrorMsg {
583 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
584 f.write_str(self.as_str())
585 }
586}
587#[derive(Debug, Clone, PartialEq, Eq)]
589#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
590pub enum NeaWeatherSubApi {
591 #[cfg_attr(feature = "serde", serde(rename = "lightning"))]
592 Lightning,
593 #[cfg_attr(feature = "serde", serde(rename = "wbgt"))]
594 WetBulbGlobeTemperature,
595}
596impl NeaWeatherSubApi {
597 pub const fn as_str(&self) -> &'static str {
598 match self {
599 Self::Lightning => "lightning",
600 Self::WetBulbGlobeTemperature => "wbgt",
601 }
602 }
603}
604impl AsRef<str> for NeaWeatherSubApi {
605 fn as_ref(&self) -> &str {
606 self.as_str()
607 }
608}
609impl fmt::Display for NeaWeatherSubApi {
610 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
611 f.write_str(self.as_str())
612 }
613}
614#[nutype::nutype(
616 validate(regex = "^S[0-9]{2,3}$", len_char_min = 3, len_char_max = 4),
617 derive(
618 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display, Hash
619 ),
620 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
621)]
622pub struct NeaStationId(String);
623#[derive(Debug, Clone, PartialEq)]
625#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
626pub struct NeaStationLocation {
627 pub latitude: NeaLatitude,
629 pub longitude: NeaLongitude,
631}
632#[derive(Debug, Clone, PartialEq, Eq)]
634#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
635pub enum NeaWindDirection16 {
636 N,
637 #[cfg_attr(feature = "serde", serde(rename = "NNE"))]
638 Nne,
639 #[cfg_attr(feature = "serde", serde(rename = "NE"))]
640 Ne,
641 #[cfg_attr(feature = "serde", serde(rename = "ENE"))]
642 Ene,
643 E,
644 #[cfg_attr(feature = "serde", serde(rename = "ESE"))]
645 Ese,
646 #[cfg_attr(feature = "serde", serde(rename = "SE"))]
647 Se,
648 #[cfg_attr(feature = "serde", serde(rename = "SSE"))]
649 Sse,
650 S,
651 #[cfg_attr(feature = "serde", serde(rename = "SSW"))]
652 Ssw,
653 #[cfg_attr(feature = "serde", serde(rename = "SW"))]
654 Sw,
655 #[cfg_attr(feature = "serde", serde(rename = "WSW"))]
656 Wsw,
657 W,
658 #[cfg_attr(feature = "serde", serde(rename = "WNW"))]
659 Wnw,
660 #[cfg_attr(feature = "serde", serde(rename = "NW"))]
661 Nw,
662 #[cfg_attr(feature = "serde", serde(rename = "NNW"))]
663 Nnw,
664}
665impl NeaWindDirection16 {
666 pub const fn as_str(&self) -> &'static str {
667 match self {
668 Self::N => "N",
669 Self::Nne => "NNE",
670 Self::Ne => "NE",
671 Self::Ene => "ENE",
672 Self::E => "E",
673 Self::Ese => "ESE",
674 Self::Se => "SE",
675 Self::Sse => "SSE",
676 Self::S => "S",
677 Self::Ssw => "SSW",
678 Self::Sw => "SW",
679 Self::Wsw => "WSW",
680 Self::W => "W",
681 Self::Wnw => "WNW",
682 Self::Nw => "NW",
683 Self::Nnw => "NNW",
684 }
685 }
686}
687impl AsRef<str> for NeaWindDirection16 {
688 fn as_ref(&self) -> &str {
689 self.as_str()
690 }
691}
692impl fmt::Display for NeaWindDirection16 {
693 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
694 f.write_str(self.as_str())
695 }
696}
697pub type NeaStringLatitude = f64;
699pub type NeaStringLongitude = f64;
701#[derive(Debug, Clone, PartialEq)]
702#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
703pub struct NeaWeatherStation {
704 pub id: NeaStationId,
706 #[cfg_attr(feature = "serde", serde(rename = "deviceId"))]
708 pub device_id: NeaStationId,
709 pub name: String,
711 pub location: NeaStationLocation,
713}
714#[derive(Debug, Clone, PartialEq)]
715#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
716pub struct NeaReadingSnapshot {
717 #[cfg_attr(
719 feature = "serde",
720 serde(with = "satay_runtime::serde_string::as_offset_datetime")
721 )]
722 pub timestamp: satay_runtime::OffsetDateTime,
723 pub data: Vec<NeaStationReading>,
724}
725#[derive(Debug, Clone, PartialEq)]
726#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
727pub struct NeaStationReading {
728 #[cfg_attr(feature = "serde", serde(rename = "stationId"))]
730 pub station_id: NeaStationId,
731 pub value: f64,
732}
733#[derive(Debug, Clone, PartialEq)]
735#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
736pub struct NeaHumidityRange {
737 pub low: NeaHumidityPercent,
739 pub high: NeaHumidityPercent,
741 pub unit: NeaMeasurementUnit,
743}
744#[derive(Debug, Clone, PartialEq)]
746#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
747pub struct NeaTemperatureRange {
748 pub low: NeaTemperatureCelsius,
750 pub high: NeaTemperatureCelsius,
752 pub unit: NeaMeasurementUnit,
754}
755#[derive(Debug, Clone, PartialEq)]
757#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
758pub struct NeaWindSpeedRange {
759 pub low: NeaWindSpeedKmh,
761 pub high: NeaWindSpeedKmh,
763}
764#[derive(Debug, Clone, PartialEq)]
765#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
766pub struct NeaOutlookWind {
767 pub speed: NeaWindSpeedRange,
769 pub direction: NeaWindDirection16,
771}
772#[derive(Debug, Clone, PartialEq)]
773#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
774pub struct NeaMssForecast {
775 pub code: NeaForecastCode,
777 pub text: NeaForecastText,
779}
780#[derive(Debug, Clone, PartialEq)]
781#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
782pub struct NeaGeoPoint {
783 pub latitude: NeaLatitude,
785 pub longitude: NeaLongitude,
787}
788#[derive(Debug, Clone, PartialEq)]
789#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
790pub struct AirTemperatureData {
791 pub stations: Vec<NeaWeatherStation>,
792 pub readings: Vec<NeaReadingSnapshot>,
793 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
795 pub reading_type: String,
796 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
798 pub reading_unit: NeaMeasurementUnit,
799 #[cfg_attr(
801 feature = "serde",
802 serde(
803 rename = "paginationToken",
804 default,
805 skip_serializing_if = "Option::is_none"
806 )
807 )]
808 pub pagination_token: Option<String>,
809}
810#[derive(Debug, Clone, PartialEq)]
811#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
812pub struct RelativeHumidityData {
813 pub stations: Vec<NeaWeatherStation>,
814 pub readings: Vec<NeaReadingSnapshot>,
815 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
817 pub reading_type: String,
818 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
820 pub reading_unit: NeaMeasurementUnit,
821 #[cfg_attr(
823 feature = "serde",
824 serde(
825 rename = "paginationToken",
826 default,
827 skip_serializing_if = "Option::is_none"
828 )
829 )]
830 pub pagination_token: Option<String>,
831}
832#[derive(Debug, Clone, PartialEq)]
833#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
834pub struct WindSpeedData {
835 pub stations: Vec<NeaWeatherStation>,
836 pub readings: Vec<NeaReadingSnapshot>,
837 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
839 pub reading_type: String,
840 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
842 pub reading_unit: NeaMeasurementUnit,
843 #[cfg_attr(
845 feature = "serde",
846 serde(
847 rename = "paginationToken",
848 default,
849 skip_serializing_if = "Option::is_none"
850 )
851 )]
852 pub pagination_token: Option<String>,
853}
854#[derive(Debug, Clone, PartialEq)]
855#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
856pub struct WindDirectionData {
857 pub stations: Vec<NeaWeatherStation>,
858 pub readings: Vec<NeaReadingSnapshot>,
859 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
861 pub reading_type: String,
862 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
864 pub reading_unit: NeaMeasurementUnit,
865 #[cfg_attr(
867 feature = "serde",
868 serde(
869 rename = "paginationToken",
870 default,
871 skip_serializing_if = "Option::is_none"
872 )
873 )]
874 pub pagination_token: Option<String>,
875}
876#[derive(Debug, Clone, PartialEq)]
877#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
878pub struct RainfallData {
879 pub stations: Vec<NeaWeatherStation>,
880 pub readings: Vec<NeaReadingSnapshot>,
881 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
883 pub reading_type: String,
884 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
886 pub reading_unit: NeaMeasurementUnit,
887 #[cfg_attr(
889 feature = "serde",
890 serde(
891 rename = "paginationToken",
892 default,
893 skip_serializing_if = "Option::is_none"
894 )
895 )]
896 pub pagination_token: Option<String>,
897}
898#[derive(Debug, Clone, PartialEq)]
900#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
901pub struct FourDayOutlookData {
902 pub records: Vec<FourDayOutlookDay>,
903}
904#[derive(Debug, Clone, PartialEq)]
905#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
906pub struct FourDayOutlookDay {
907 #[cfg_attr(
909 feature = "serde",
910 serde(with = "satay_runtime::serde_string::as_date")
911 )]
912 pub date: satay_runtime::Date,
913 #[cfg_attr(
915 feature = "serde",
916 serde(
917 rename = "updatedTimestamp",
918 with = "satay_runtime::serde_string::as_offset_datetime"
919 )
920 )]
921 pub updated_timestamp: satay_runtime::OffsetDateTime,
922 #[cfg_attr(
924 feature = "serde",
925 serde(with = "satay_runtime::serde_string::as_offset_datetime")
926 )]
927 pub timestamp: satay_runtime::OffsetDateTime,
928 pub forecasts: Vec<FourDayOutlookPeriod>,
930}
931#[derive(Debug, Clone, PartialEq)]
932#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
933pub struct FourDayOutlookPeriod {
934 #[cfg_attr(
936 feature = "serde",
937 serde(with = "satay_runtime::serde_string::as_offset_datetime")
938 )]
939 pub timestamp: satay_runtime::OffsetDateTime,
940 pub temperature: NeaTemperatureRange,
942 #[cfg_attr(feature = "serde", serde(rename = "relativeHumidity"))]
944 pub relative_humidity: NeaHumidityRange,
945 pub forecast: NeaOutlookForecastDetail,
946 pub day: NeaDayOfWeek,
948 pub wind: NeaOutlookWind,
949}
950#[derive(Debug, Clone, PartialEq)]
951#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
952pub struct NeaOutlookForecastDetail {
953 pub summary: String,
954 pub code: NeaForecastCode,
956 pub text: NeaForecastText,
958}
959#[derive(Debug, Clone, PartialEq)]
960#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
961pub struct TwentyFourHrForecastData {
962 #[cfg_attr(
963 feature = "serde",
964 serde(default, skip_serializing_if = "Option::is_none")
965 )]
966 pub area_metadata: Option<Vec<NeaForecastArea>>,
967 pub records: Vec<TwentyFourHrForecastDay>,
968 #[cfg_attr(
970 feature = "serde",
971 serde(
972 rename = "paginationToken",
973 default,
974 skip_serializing_if = "Option::is_none"
975 )
976 )]
977 pub pagination_token: Option<String>,
978}
979#[derive(Debug, Clone, PartialEq)]
980#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
981pub struct TwentyFourHrForecastDay {
982 #[cfg_attr(
984 feature = "serde",
985 serde(with = "satay_runtime::serde_string::as_date")
986 )]
987 pub date: satay_runtime::Date,
988 #[cfg_attr(
990 feature = "serde",
991 serde(
992 rename = "updatedTimestamp",
993 with = "satay_runtime::serde_string::as_offset_datetime"
994 )
995 )]
996 pub updated_timestamp: satay_runtime::OffsetDateTime,
997 #[cfg_attr(
999 feature = "serde",
1000 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1001 )]
1002 pub timestamp: satay_runtime::OffsetDateTime,
1003 pub general: TwentyFourHrForecastGeneral,
1005 pub periods: Vec<TwentyFourHrForecastPeriod>,
1007}
1008#[derive(Debug, Clone, PartialEq)]
1010#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1011pub struct TwentyFourHrForecastGeneral {
1012 #[cfg_attr(feature = "serde", serde(rename = "validPeriod"))]
1014 pub valid_period: NeaValidPeriod,
1015 pub temperature: NeaTemperatureRange,
1017 #[cfg_attr(feature = "serde", serde(rename = "relativeHumidity"))]
1019 pub relative_humidity: NeaHumidityRange,
1020 pub forecast: NeaMssForecast,
1021 pub wind: NeaOutlookWind,
1022}
1023#[derive(Debug, Clone, PartialEq)]
1024#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1025pub struct TwentyFourHrForecastPeriod {
1026 #[cfg_attr(feature = "serde", serde(rename = "timePeriod"))]
1028 pub time_period: NeaValidPeriod,
1029 pub regions: TwentyFourHrRegionalForecast,
1030}
1031#[derive(Debug, Clone, PartialEq)]
1032#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1033pub struct TwentyFourHrRegionalForecast {
1034 pub west: NeaMssForecast,
1035 pub east: NeaMssForecast,
1036 pub central: NeaMssForecast,
1037 pub north: NeaMssForecast,
1038 pub south: NeaMssForecast,
1039}
1040#[derive(Debug, Clone, PartialEq)]
1041#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1042pub struct TwoHrForecastData {
1043 pub area_metadata: Vec<NeaForecastArea>,
1044 pub items: Vec<TwoHrForecastSnapshot>,
1045 #[cfg_attr(
1047 feature = "serde",
1048 serde(
1049 rename = "paginationToken",
1050 default,
1051 skip_serializing_if = "Option::is_none"
1052 )
1053 )]
1054 pub pagination_token: Option<String>,
1055}
1056#[derive(Debug, Clone, PartialEq)]
1057#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1058pub struct NeaForecastArea {
1059 pub name: String,
1061 pub label_location: NeaGeoPoint,
1062}
1063#[derive(Debug, Clone, PartialEq)]
1064#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1065pub struct TwoHrForecastSnapshot {
1066 #[cfg_attr(
1068 feature = "serde",
1069 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1070 )]
1071 pub update_timestamp: satay_runtime::OffsetDateTime,
1072 #[cfg_attr(
1074 feature = "serde",
1075 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1076 )]
1077 pub timestamp: satay_runtime::OffsetDateTime,
1078 pub valid_period: NeaValidPeriod,
1080 pub forecasts: Vec<TwoHrAreaForecast>,
1082}
1083#[derive(Debug, Clone, PartialEq)]
1084#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1085pub struct TwoHrAreaForecast {
1086 pub area: String,
1087 pub forecast: NeaForecastText,
1089}
1090#[derive(Debug, Clone, PartialEq)]
1092#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1093pub struct NeaValidPeriod {
1094 #[cfg_attr(
1096 feature = "serde",
1097 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1098 )]
1099 pub start: satay_runtime::OffsetDateTime,
1100 #[cfg_attr(
1102 feature = "serde",
1103 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1104 )]
1105 pub end: satay_runtime::OffsetDateTime,
1106 pub text: String,
1107}
1108#[derive(Debug, Clone, PartialEq)]
1109#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1110pub struct PsiData {
1111 #[cfg_attr(feature = "serde", serde(rename = "regionMetadata"))]
1112 pub region_metadata: Vec<NeaRegionMetadata>,
1113 pub items: Vec<PsiSnapshot>,
1114 #[cfg_attr(
1116 feature = "serde",
1117 serde(
1118 rename = "paginationToken",
1119 default,
1120 skip_serializing_if = "Option::is_none"
1121 )
1122 )]
1123 pub pagination_token: Option<String>,
1124}
1125#[derive(Debug, Clone, PartialEq)]
1126#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1127pub struct PsiSnapshot {
1128 #[cfg_attr(
1130 feature = "serde",
1131 serde(with = "satay_runtime::serde_string::as_date")
1132 )]
1133 pub date: satay_runtime::Date,
1134 #[cfg_attr(
1136 feature = "serde",
1137 serde(
1138 rename = "updatedTimestamp",
1139 with = "satay_runtime::serde_string::as_offset_datetime"
1140 )
1141 )]
1142 pub updated_timestamp: satay_runtime::OffsetDateTime,
1143 #[cfg_attr(
1145 feature = "serde",
1146 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1147 )]
1148 pub timestamp: satay_runtime::OffsetDateTime,
1149 pub readings: PsiReadings,
1151}
1152#[derive(Debug, Clone, PartialEq)]
1154#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1155pub struct PsiReadings {
1156 pub co_sub_index: PsiCoSubIndexRegional,
1158 pub so2_twenty_four_hourly: PsiSo2TwentyFourHourRegional,
1160 pub so2_sub_index: PsiSo2SubIndexRegional,
1162 #[cfg_attr(
1164 feature = "serde",
1165 serde(default, skip_serializing_if = "Option::is_none")
1166 )]
1167 pub psi_three_hourly: Option<PsiThreeHourRegional>,
1168 pub co_eight_hour_max: PsiCoEightHourMaxRegional,
1170 pub no2_one_hour_max: PsiNo2OneHourMaxRegional,
1172 pub pm10_sub_index: PsiPm10SubIndexRegional,
1174 pub pm25_sub_index: PsiPm25SubIndexRegional,
1176 pub o3_eight_hour_max: PsiO3EightHourMaxRegional,
1178 pub psi_twenty_four_hourly: PsiTwentyFourHourRegional,
1180 pub o3_sub_index: PsiO3SubIndexRegional,
1182 pub pm25_twenty_four_hourly: PsiPm25TwentyFourHourRegional,
1184 pub pm10_twenty_four_hourly: PsiPm10TwentyFourHourRegional,
1186}
1187#[derive(Debug, Clone, PartialEq)]
1188#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1189pub struct NeaRegionMetadata {
1190 pub name: NeaRegionMetadataName,
1192 #[cfg_attr(feature = "serde", serde(rename = "labelLocation"))]
1193 pub label_location: NeaGeoPoint,
1194}
1195#[derive(Debug, Clone, PartialEq)]
1197#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1198pub struct PsiCoEightHourMaxRegional {
1199 pub east: NeaRegionalReading,
1201 pub west: NeaRegionalReading,
1203 pub north: NeaRegionalReading,
1205 pub south: NeaRegionalReading,
1207 pub central: NeaRegionalReading,
1209}
1210#[derive(Debug, Clone, PartialEq)]
1212#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1213pub struct PsiCoSubIndexRegional {
1214 pub east: NeaRegionalReading,
1216 pub west: NeaRegionalReading,
1218 pub north: NeaRegionalReading,
1220 pub south: NeaRegionalReading,
1222 pub central: NeaRegionalReading,
1224}
1225#[derive(Debug, Clone, PartialEq)]
1227#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1228pub struct PsiNo2OneHourMaxRegional {
1229 pub east: NeaRegionalReading,
1231 pub west: NeaRegionalReading,
1233 pub north: NeaRegionalReading,
1235 pub south: NeaRegionalReading,
1237 pub central: NeaRegionalReading,
1239}
1240#[derive(Debug, Clone, PartialEq)]
1242#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1243pub struct PsiO3EightHourMaxRegional {
1244 pub east: NeaRegionalReading,
1246 pub west: NeaRegionalReading,
1248 pub north: NeaRegionalReading,
1250 pub south: NeaRegionalReading,
1252 pub central: NeaRegionalReading,
1254}
1255#[derive(Debug, Clone, PartialEq)]
1257#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1258pub struct PsiO3SubIndexRegional {
1259 pub east: NeaRegionalReading,
1261 pub west: NeaRegionalReading,
1263 pub north: NeaRegionalReading,
1265 pub south: NeaRegionalReading,
1267 pub central: NeaRegionalReading,
1269}
1270#[derive(Debug, Clone, PartialEq)]
1272#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1273pub struct PsiPm10SubIndexRegional {
1274 pub east: NeaRegionalReading,
1276 pub west: NeaRegionalReading,
1278 pub north: NeaRegionalReading,
1280 pub south: NeaRegionalReading,
1282 pub central: NeaRegionalReading,
1284}
1285#[derive(Debug, Clone, PartialEq)]
1287#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1288pub struct PsiPm10TwentyFourHourRegional {
1289 pub east: NeaRegionalReading,
1291 pub west: NeaRegionalReading,
1293 pub north: NeaRegionalReading,
1295 pub south: NeaRegionalReading,
1297 pub central: NeaRegionalReading,
1299}
1300#[derive(Debug, Clone, PartialEq)]
1302#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1303pub struct PsiPm25SubIndexRegional {
1304 pub east: NeaRegionalReading,
1306 pub west: NeaRegionalReading,
1308 pub north: NeaRegionalReading,
1310 pub south: NeaRegionalReading,
1312 pub central: NeaRegionalReading,
1314}
1315#[derive(Debug, Clone, PartialEq)]
1317#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1318pub struct PsiPm25TwentyFourHourRegional {
1319 pub east: NeaRegionalReading,
1321 pub west: NeaRegionalReading,
1323 pub north: NeaRegionalReading,
1325 pub south: NeaRegionalReading,
1327 pub central: NeaRegionalReading,
1329}
1330#[derive(Debug, Clone, PartialEq)]
1332#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1333pub struct PsiThreeHourRegional {
1334 #[cfg_attr(
1336 feature = "serde",
1337 serde(default, skip_serializing_if = "Option::is_none")
1338 )]
1339 pub east: Option<NeaRegionalReading>,
1340 #[cfg_attr(
1342 feature = "serde",
1343 serde(default, skip_serializing_if = "Option::is_none")
1344 )]
1345 pub west: Option<NeaRegionalReading>,
1346 #[cfg_attr(
1348 feature = "serde",
1349 serde(default, skip_serializing_if = "Option::is_none")
1350 )]
1351 pub north: Option<NeaRegionalReading>,
1352 #[cfg_attr(
1354 feature = "serde",
1355 serde(default, skip_serializing_if = "Option::is_none")
1356 )]
1357 pub south: Option<NeaRegionalReading>,
1358 #[cfg_attr(
1360 feature = "serde",
1361 serde(default, skip_serializing_if = "Option::is_none")
1362 )]
1363 pub central: Option<NeaRegionalReading>,
1364}
1365#[derive(Debug, Clone, PartialEq)]
1367#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1368pub struct PsiTwentyFourHourRegional {
1369 pub east: NeaRegionalReading,
1371 pub west: NeaRegionalReading,
1373 pub north: NeaRegionalReading,
1375 pub south: NeaRegionalReading,
1377 pub central: NeaRegionalReading,
1379}
1380#[derive(Debug, Clone, PartialEq)]
1382#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1383pub struct PsiSo2SubIndexRegional {
1384 pub east: NeaRegionalReading,
1386 pub west: NeaRegionalReading,
1388 pub north: NeaRegionalReading,
1390 pub south: NeaRegionalReading,
1392 pub central: NeaRegionalReading,
1394}
1395#[derive(Debug, Clone, PartialEq)]
1397#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1398pub struct PsiSo2TwentyFourHourRegional {
1399 pub east: NeaRegionalReading,
1401 pub west: NeaRegionalReading,
1403 pub north: NeaRegionalReading,
1405 pub south: NeaRegionalReading,
1407 pub central: NeaRegionalReading,
1409}
1410#[derive(Debug, Clone, PartialEq)]
1411#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1412pub struct Pm25Data {
1413 #[cfg_attr(feature = "serde", serde(rename = "regionMetadata"))]
1414 pub region_metadata: Vec<NeaRegionMetadata>,
1415 pub items: Vec<Pm25Snapshot>,
1416 #[cfg_attr(
1418 feature = "serde",
1419 serde(
1420 rename = "paginationToken",
1421 default,
1422 skip_serializing_if = "Option::is_none"
1423 )
1424 )]
1425 pub pagination_token: Option<String>,
1426}
1427#[derive(Debug, Clone, PartialEq)]
1428#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1429pub struct Pm25Snapshot {
1430 #[cfg_attr(
1432 feature = "serde",
1433 serde(with = "satay_runtime::serde_string::as_date")
1434 )]
1435 pub date: satay_runtime::Date,
1436 #[cfg_attr(
1438 feature = "serde",
1439 serde(
1440 rename = "updatedTimestamp",
1441 with = "satay_runtime::serde_string::as_offset_datetime"
1442 )
1443 )]
1444 pub updated_timestamp: satay_runtime::OffsetDateTime,
1445 #[cfg_attr(
1447 feature = "serde",
1448 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1449 )]
1450 pub timestamp: satay_runtime::OffsetDateTime,
1451 pub readings: Pm25Readings,
1453}
1454#[derive(Debug, Clone, PartialEq)]
1456#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1457pub struct Pm25Readings {
1458 pub pm25_one_hourly: Pm25OneHourRegional,
1459}
1460#[derive(Debug, Clone, PartialEq)]
1461#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1462pub struct Pm25OneHourRegional {
1463 pub east: NeaPm25HourlyReading,
1465 pub west: NeaPm25HourlyReading,
1467 pub north: NeaPm25HourlyReading,
1469 pub south: NeaPm25HourlyReading,
1471 pub central: NeaPm25HourlyReading,
1473}
1474#[derive(Debug, Clone, PartialEq)]
1475#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1476pub struct UvData {
1477 pub records: Vec<UvDayRecord>,
1478 #[cfg_attr(
1480 feature = "serde",
1481 serde(
1482 rename = "paginationToken",
1483 default,
1484 skip_serializing_if = "Option::is_none"
1485 )
1486 )]
1487 pub pagination_token: Option<String>,
1488}
1489#[derive(Debug, Clone, PartialEq)]
1490#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1491pub struct UvDayRecord {
1492 pub index: Vec<UvHourlyIndex>,
1493 #[cfg_attr(
1495 feature = "serde",
1496 serde(with = "satay_runtime::serde_string::as_date")
1497 )]
1498 pub date: satay_runtime::Date,
1499 #[cfg_attr(
1501 feature = "serde",
1502 serde(
1503 rename = "updatedTimestamp",
1504 with = "satay_runtime::serde_string::as_offset_datetime"
1505 )
1506 )]
1507 pub updated_timestamp: satay_runtime::OffsetDateTime,
1508 #[cfg_attr(
1510 feature = "serde",
1511 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1512 )]
1513 pub timestamp: satay_runtime::OffsetDateTime,
1514}
1515#[derive(Debug, Clone, PartialEq)]
1517#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1518pub struct UvHourlyIndex {
1519 #[cfg_attr(
1521 feature = "serde",
1522 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1523 )]
1524 pub hour: satay_runtime::OffsetDateTime,
1525 pub value: NeaUvIndex,
1527}
1528#[derive(Debug, Clone, PartialEq)]
1529#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1530pub struct WeatherSubApiData {
1531 #[cfg_attr(
1532 feature = "serde",
1533 serde(default, skip_serializing_if = "Option::is_none")
1534 )]
1535 pub records: Option<Vec<WeatherSubApiDayRecord>>,
1536 #[cfg_attr(
1538 feature = "serde",
1539 serde(
1540 rename = "paginationToken",
1541 default,
1542 skip_serializing_if = "Option::is_none"
1543 )
1544 )]
1545 pub pagination_token: Option<String>,
1546}
1547#[derive(Debug, Clone, PartialEq)]
1548#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1549pub struct WeatherSubApiDayRecord {
1550 #[cfg_attr(
1552 feature = "serde",
1553 serde(
1554 with = "satay_runtime::serde_string::as_offset_datetime::option",
1555 default,
1556 skip_serializing_if = "Option::is_none"
1557 )
1558 )]
1559 pub datetime: Option<satay_runtime::OffsetDateTime>,
1560 #[cfg_attr(
1562 feature = "serde",
1563 serde(default, skip_serializing_if = "Option::is_none")
1564 )]
1565 pub item: Option<WeatherSubApiObservation>,
1566 #[cfg_attr(
1568 feature = "serde",
1569 serde(
1570 rename = "updatedTimestamp",
1571 with = "satay_runtime::serde_string::as_offset_datetime::option",
1572 default,
1573 skip_serializing_if = "Option::is_none"
1574 )
1575 )]
1576 pub updated_timestamp: Option<satay_runtime::OffsetDateTime>,
1577}
1578#[derive(Debug, Clone, PartialEq)]
1580#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1581pub struct WeatherSubApiObservation {
1582 #[cfg_attr(
1584 feature = "serde",
1585 serde(default, skip_serializing_if = "Option::is_none")
1586 )]
1587 pub r#type: Option<String>,
1588 #[cfg_attr(
1590 feature = "serde",
1591 serde(
1592 rename = "isStationData",
1593 default,
1594 skip_serializing_if = "Option::is_none"
1595 )
1596 )]
1597 pub is_station_data: Option<bool>,
1598 #[cfg_attr(
1599 feature = "serde",
1600 serde(default, skip_serializing_if = "Option::is_none")
1601 )]
1602 pub readings: Option<Vec<WeatherSubApiLightningReading>>,
1603}
1604#[derive(Debug, Clone, PartialEq)]
1605#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1606pub struct WeatherSubApiLightningReading {
1607 #[cfg_attr(
1609 feature = "serde",
1610 serde(default, skip_serializing_if = "Option::is_none")
1611 )]
1612 pub location: Option<NeaLightningGeoPoint>,
1613 #[cfg_attr(
1615 feature = "serde",
1616 serde(
1617 with = "satay_runtime::serde_string::as_offset_datetime::option",
1618 default,
1619 skip_serializing_if = "Option::is_none"
1620 )
1621 )]
1622 pub datetime: Option<satay_runtime::OffsetDateTime>,
1623 #[cfg_attr(
1625 feature = "serde",
1626 serde(default, skip_serializing_if = "Option::is_none")
1627 )]
1628 pub text: Option<String>,
1629 #[cfg_attr(
1631 feature = "serde",
1632 serde(default, skip_serializing_if = "Option::is_none")
1633 )]
1634 pub r#type: Option<NeaLightningType>,
1635 #[cfg_attr(
1637 feature = "serde",
1638 serde(default, skip_serializing_if = "Option::is_none")
1639 )]
1640 pub station: Option<NeaWbgtStation>,
1641 #[cfg_attr(
1643 feature = "serde",
1644 serde(
1645 deserialize_with = "WeatherSubApiLightningReading::__satay_deserialize_wbgt_none_if",
1646 serialize_with = "WeatherSubApiLightningReading::__satay_serialize_wbgt_none_if",
1647 default,
1648 skip_serializing_if = "Option::is_none"
1649 )
1650 )]
1651 pub wbgt: Option<f64>,
1652 #[cfg_attr(
1654 feature = "serde",
1655 serde(
1656 rename = "heatStress",
1657 default,
1658 skip_serializing_if = "Option::is_none"
1659 )
1660 )]
1661 pub heat_stress: Option<NeaHeatStressLevel>,
1662}
1663#[cfg(feature = "serde")]
1664impl WeatherSubApiLightningReading {
1665 fn __satay_deserialize_wbgt_none_if<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
1666 where
1667 D: serde::Deserializer<'de>,
1668 {
1669 satay_runtime::serde_string::as_f64::option::deserialize_none_if(deserializer, &["NA"])
1670 }
1671 #[allow(clippy::ref_option)]
1672 fn __satay_serialize_wbgt_none_if<S>(
1673 value: &Option<f64>,
1674 serializer: S,
1675 ) -> Result<S::Ok, S::Error>
1676 where
1677 S: serde::Serializer,
1678 {
1679 satay_runtime::serde_string::as_f64::serialize_none_if(value, "NA", serializer)
1680 }
1681}
1682#[derive(Debug, Clone, PartialEq)]
1683#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1684pub struct WeatherSubApiInvalidParamsError {
1685 #[cfg_attr(
1686 feature = "serde",
1687 serde(default, skip_serializing_if = "Option::is_none")
1688 )]
1689 pub code: Option<f64>,
1690 #[cfg_attr(
1691 feature = "serde",
1692 serde(default, skip_serializing_if = "Option::is_none")
1693 )]
1694 pub name: Option<String>,
1695 #[cfg_attr(
1696 feature = "serde",
1697 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
1698 )]
1699 pub error_msg: Option<String>,
1700}
1701#[derive(Debug, Clone, PartialEq, Eq)]
1703#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1704pub enum NeaMeasurementUnit {
1705 #[cfg_attr(feature = "serde", serde(rename = "deg C"))]
1706 DegC,
1707 #[cfg_attr(feature = "serde", serde(rename = "Degrees Celsius"))]
1708 DegreesCelsius,
1709 Percentage,
1710 #[cfg_attr(feature = "serde", serde(rename = "percentage"))]
1711 PercentLower,
1712 #[cfg_attr(feature = "serde", serde(rename = "knots"))]
1713 Knots,
1714 #[cfg_attr(feature = "serde", serde(rename = "degrees"))]
1715 Degrees,
1716 #[cfg_attr(feature = "serde", serde(rename = "mm"))]
1717 Millimeters,
1718}
1719impl NeaMeasurementUnit {
1720 pub const fn as_str(&self) -> &'static str {
1721 match self {
1722 Self::DegC => "deg C",
1723 Self::DegreesCelsius => "Degrees Celsius",
1724 Self::Percentage => "Percentage",
1725 Self::PercentLower => "percentage",
1726 Self::Knots => "knots",
1727 Self::Degrees => "degrees",
1728 Self::Millimeters => "mm",
1729 }
1730 }
1731}
1732impl AsRef<str> for NeaMeasurementUnit {
1733 fn as_ref(&self) -> &str {
1734 self.as_str()
1735 }
1736}
1737impl fmt::Display for NeaMeasurementUnit {
1738 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1739 f.write_str(self.as_str())
1740 }
1741}
1742#[derive(Debug, Clone, PartialEq)]
1744#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1745pub struct NeaLightningGeoPoint {
1746 #[cfg_attr(feature = "serde", serde(with = "satay_runtime::serde_string::as_f64"))]
1748 pub latitude: f64,
1749 #[cfg_attr(feature = "serde", serde(with = "satay_runtime::serde_string::as_f64"))]
1751 pub longitude: f64,
1752}
1753#[derive(Debug, Clone, PartialEq)]
1755#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1756pub struct NeaWbgtStation {
1757 pub id: NeaStationId,
1759 pub name: String,
1761 #[cfg_attr(feature = "serde", serde(rename = "townCenter"))]
1763 pub town_center: String,
1764}
1765#[derive(Debug, Clone, PartialEq, Eq)]
1767#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1768pub enum NeaHeatStressLevel {
1769 Low,
1770 Moderate,
1771 High,
1772 #[cfg_attr(feature = "serde", serde(rename = "NA"))]
1773 NotAvailable,
1774}
1775impl NeaHeatStressLevel {
1776 pub const fn as_str(&self) -> &'static str {
1777 match self {
1778 Self::Low => "Low",
1779 Self::Moderate => "Moderate",
1780 Self::High => "High",
1781 Self::NotAvailable => "NA",
1782 }
1783 }
1784}
1785impl AsRef<str> for NeaHeatStressLevel {
1786 fn as_ref(&self) -> &str {
1787 self.as_str()
1788 }
1789}
1790impl fmt::Display for NeaHeatStressLevel {
1791 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1792 f.write_str(self.as_str())
1793 }
1794}
1795#[derive(Debug, Clone, PartialEq, Eq)]
1797#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1798pub enum NeaRegionMetadataName {
1799 #[cfg_attr(feature = "serde", serde(rename = "west"))]
1800 West,
1801 #[cfg_attr(feature = "serde", serde(rename = "east"))]
1802 East,
1803 #[cfg_attr(feature = "serde", serde(rename = "north"))]
1804 North,
1805 #[cfg_attr(feature = "serde", serde(rename = "south"))]
1806 South,
1807 #[cfg_attr(feature = "serde", serde(rename = "central"))]
1808 Central,
1809}
1810impl NeaRegionMetadataName {
1811 pub const fn as_str(&self) -> &'static str {
1812 match self {
1813 Self::West => "west",
1814 Self::East => "east",
1815 Self::North => "north",
1816 Self::South => "south",
1817 Self::Central => "central",
1818 }
1819 }
1820}
1821impl AsRef<str> for NeaRegionMetadataName {
1822 fn as_ref(&self) -> &str {
1823 self.as_str()
1824 }
1825}
1826impl fmt::Display for NeaRegionMetadataName {
1827 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1828 f.write_str(self.as_str())
1829 }
1830}