1use std::fmt;
4#[derive(Debug, Clone, PartialEq)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct PsiResponse {
7 pub code: NeaSuccessCode,
9 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
11 pub error_msg: String,
12 pub data: PsiData,
13}
14#[derive(Debug, Clone, PartialEq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct Pm25Response {
17 pub code: NeaSuccessCode,
19 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
21 pub error_msg: String,
22 pub data: Pm25Data,
23}
24#[derive(Debug, Clone, PartialEq)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26pub struct AirTemperatureResponse {
27 pub code: NeaSuccessCode,
29 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
31 pub error_msg: String,
32 pub data: AirTemperatureData,
33}
34#[derive(Debug, Clone, PartialEq)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
36pub struct RelativeHumidityResponse {
37 pub code: NeaSuccessCode,
39 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
41 pub error_msg: String,
42 pub data: RelativeHumidityData,
43}
44#[derive(Debug, Clone, PartialEq)]
45#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
46pub struct WindSpeedResponse {
47 pub code: NeaSuccessCode,
49 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
51 pub error_msg: String,
52 pub data: WindSpeedData,
53}
54#[derive(Debug, Clone, PartialEq)]
55#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56pub struct WindDirectionResponse {
57 pub code: NeaSuccessCode,
59 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
61 pub error_msg: String,
62 pub data: WindDirectionData,
63}
64#[derive(Debug, Clone, PartialEq)]
65#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
66pub struct RainfallResponse {
67 pub code: NeaSuccessCode,
69 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
71 pub error_msg: String,
72 pub data: RainfallData,
73}
74#[derive(Debug, Clone, PartialEq)]
75#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
76pub struct TwoHrForecastResponse {
77 pub code: NeaSuccessCode,
79 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
81 pub error_msg: String,
82 pub data: TwoHrForecastData,
83}
84#[derive(Debug, Clone, PartialEq)]
85#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
86pub struct TwentyFourHrForecastResponse {
87 pub code: NeaSuccessCode,
89 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
91 pub error_msg: String,
92 pub data: TwentyFourHrForecastData,
93}
94#[derive(Debug, Clone, PartialEq)]
95#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
96pub struct FourDayOutlookResponse {
97 pub code: NeaSuccessCode,
99 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
101 pub error_msg: String,
102 pub data: FourDayOutlookData,
104}
105#[derive(Debug, Clone, PartialEq)]
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
107pub struct UvResponse {
108 pub code: NeaSuccessCode,
110 #[cfg_attr(feature = "serde", serde(rename = "errorMsg"))]
112 pub error_msg: String,
113 pub data: UvData,
114}
115#[derive(Debug, Clone, PartialEq)]
116#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
117pub struct WeatherSubApiResponse {
118 #[cfg_attr(
120 feature = "serde",
121 serde(default, skip_serializing_if = "Option::is_none")
122 )]
123 pub code: Option<NeaSuccessCode>,
124 #[cfg_attr(
126 feature = "serde",
127 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
128 )]
129 pub error_msg: Option<String>,
130 #[cfg_attr(
131 feature = "serde",
132 serde(default, skip_serializing_if = "Option::is_none")
133 )]
134 pub data: Option<WeatherSubApiData>,
135}
136#[derive(Debug, Clone, PartialEq)]
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138pub struct InvalidParamsError {
139 #[cfg_attr(
140 feature = "serde",
141 serde(default, skip_serializing_if = "Option::is_none")
142 )]
143 pub code: Option<f64>,
144 #[cfg_attr(
145 feature = "serde",
146 serde(default, skip_serializing_if = "Option::is_none")
147 )]
148 pub name: Option<String>,
149 #[cfg_attr(
151 feature = "serde",
152 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
153 )]
154 pub error_msg: Option<NeaInvalidParamsErrorMsg>,
155}
156#[derive(Debug, Clone, PartialEq)]
157#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
158pub struct InvalidParamsError22 {
159 #[cfg_attr(
160 feature = "serde",
161 serde(default, skip_serializing_if = "Option::is_none")
162 )]
163 pub code: Option<f64>,
164 #[cfg_attr(
165 feature = "serde",
166 serde(default, skip_serializing_if = "Option::is_none")
167 )]
168 pub name: Option<String>,
169 #[cfg_attr(
170 feature = "serde",
171 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
172 )]
173 pub error_msg: Option<String>,
174}
175#[derive(Debug, Clone, PartialEq)]
176#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
177pub struct DataNotFoundError {
178 #[cfg_attr(
179 feature = "serde",
180 serde(default, skip_serializing_if = "Option::is_none")
181 )]
182 pub code: Option<f64>,
183 #[cfg_attr(
184 feature = "serde",
185 serde(default, skip_serializing_if = "Option::is_none")
186 )]
187 pub name: Option<String>,
188 #[cfg_attr(
189 feature = "serde",
190 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
191 )]
192 pub error_msg: Option<String>,
193}
194#[derive(Debug, Clone, PartialEq)]
195#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
196pub struct RateLimitError {
197 #[cfg_attr(
198 feature = "serde",
199 serde(default, skip_serializing_if = "Option::is_none")
200 )]
201 pub code: Option<f64>,
202 #[cfg_attr(
203 feature = "serde",
204 serde(default, skip_serializing_if = "Option::is_none")
205 )]
206 pub name: Option<String>,
207 #[cfg_attr(
208 feature = "serde",
209 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
210 )]
211 pub error_msg: Option<String>,
212}
213#[derive(Debug, Clone, PartialEq)]
214#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
215pub struct MissingAuthResponse {
216 #[cfg_attr(
217 feature = "serde",
218 serde(default, skip_serializing_if = "Option::is_none")
219 )]
220 pub message: Option<String>,
221}
222#[nutype::nutype(
224 validate(less_or_equal = 0),
225 derive(
226 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
227 ),
228 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
229)]
230pub struct NeaSuccessCode(u8);
231pub type NeaOffsetDateTime = satay_runtime::OffsetDateTime;
233pub type NeaDate = satay_runtime::Date;
235#[nutype::nutype(
237 validate(finite, greater_or_equal = 1.0, less_or_equal = 1.5),
238 derive(
239 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
240 ),
241 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
242)]
243pub struct NeaLatitude(f64);
244#[nutype::nutype(
246 validate(finite, greater_or_equal = 103.5, less_or_equal = 104.2),
247 derive(
248 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
249 ),
250 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
251)]
252pub struct NeaLongitude(f64);
253#[nutype::nutype(
255 validate(less_or_equal = 500),
256 derive(
257 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
258 ),
259 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
260)]
261pub struct NeaRegionalReading(u16);
262#[nutype::nutype(
264 validate(less_or_equal = 500),
265 derive(
266 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
267 ),
268 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
269)]
270pub struct NeaPm25HourlyReading(u16);
271#[nutype::nutype(
273 validate(less_or_equal = 360),
274 derive(
275 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
276 ),
277 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
278)]
279pub struct NeaWindDirectionDegrees(u16);
280#[nutype::nutype(
282 validate(less_or_equal = 16),
283 derive(
284 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display
285 ),
286 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
287)]
288pub struct NeaUvIndex(u8);
289#[nutype::nutype(
291 validate(finite, greater_or_equal = 0.0, less_or_equal = 100.0),
292 derive(
293 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
294 ),
295 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
296)]
297pub struct NeaHumidityPercent(f64);
298#[nutype::nutype(
300 validate(finite, greater_or_equal = 15.0, less_or_equal = 45.0),
301 derive(
302 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
303 ),
304 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
305)]
306pub struct NeaTemperatureCelsius(f64);
307#[nutype::nutype(
309 validate(finite, greater_or_equal = 0.0, less_or_equal = 120.0),
310 derive(
311 Debug, Clone, Copy, PartialEq, PartialOrd, AsRef, Deref, TryFrom, Into, Display
312 ),
313 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
314)]
315pub struct NeaWindSpeedKmh(f64);
316#[derive(Debug, Clone, PartialEq, Eq, Default)]
318#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
319pub enum NeaForecastCode {
320 #[cfg_attr(feature = "serde", serde(rename = "FA"))]
321 FairDay,
322 #[cfg_attr(feature = "serde", serde(rename = "FN"))]
323 FairNight,
324 #[cfg_attr(feature = "serde", serde(rename = "FW"))]
325 FairAndWarm,
326 #[cfg_attr(feature = "serde", serde(rename = "CL"))]
327 Cloudy,
328 #[cfg_attr(feature = "serde", serde(rename = "PC"))]
329 PartlyCloudyDay,
330 #[cfg_attr(feature = "serde", serde(rename = "PN"))]
331 PartlyCloudyNight,
332 #[cfg_attr(feature = "serde", serde(rename = "HZ"))]
333 Hazy,
334 #[cfg_attr(feature = "serde", serde(rename = "SH"))]
335 SlightlyHazy,
336 #[cfg_attr(feature = "serde", serde(rename = "WI"))]
337 Windy,
338 #[cfg_attr(feature = "serde", serde(rename = "MS"))]
339 Mist,
340 #[cfg_attr(feature = "serde", serde(rename = "FG"))]
341 Fog,
342 #[cfg_attr(feature = "serde", serde(rename = "LR"))]
343 LightRain,
344 #[cfg_attr(feature = "serde", serde(rename = "MR"))]
345 ModerateRain,
346 #[cfg_attr(feature = "serde", serde(rename = "HR"))]
347 HeavyRain,
348 #[cfg_attr(feature = "serde", serde(rename = "PS"))]
349 PassingShowers,
350 #[cfg_attr(feature = "serde", serde(rename = "LS"))]
351 LightShowers,
352 #[cfg_attr(feature = "serde", serde(rename = "HS"))]
353 HeavyShowers,
354 #[cfg_attr(feature = "serde", serde(rename = "TS"))]
355 ThunderyShowers,
356 #[cfg_attr(feature = "serde", serde(rename = "HT"))]
357 HeavyThunderyShowers,
358 #[cfg_attr(feature = "serde", serde(rename = "HG"))]
359 HeavyThunderyShowersWithGustyWinds,
360 #[cfg_attr(feature = "serde", serde(rename = "TL"))]
361 ThunderyShowersAlt,
362 #[default]
363 #[cfg_attr(feature = "serde", serde(other))]
364 Unknown,
365}
366impl NeaForecastCode {
367 pub const fn as_str(&self) -> &'static str {
368 match self {
369 Self::FairDay => "FA",
370 Self::FairNight => "FN",
371 Self::FairAndWarm => "FW",
372 Self::Cloudy => "CL",
373 Self::PartlyCloudyDay => "PC",
374 Self::PartlyCloudyNight => "PN",
375 Self::Hazy => "HZ",
376 Self::SlightlyHazy => "SH",
377 Self::Windy => "WI",
378 Self::Mist => "MS",
379 Self::Fog => "FG",
380 Self::LightRain => "LR",
381 Self::ModerateRain => "MR",
382 Self::HeavyRain => "HR",
383 Self::PassingShowers => "PS",
384 Self::LightShowers => "LS",
385 Self::HeavyShowers => "HS",
386 Self::ThunderyShowers => "TS",
387 Self::HeavyThunderyShowers => "HT",
388 Self::HeavyThunderyShowersWithGustyWinds => "HG",
389 Self::ThunderyShowersAlt => "TL",
390 Self::Unknown => "",
391 }
392 }
393}
394impl AsRef<str> for NeaForecastCode {
395 fn as_ref(&self) -> &str {
396 self.as_str()
397 }
398}
399impl fmt::Display for NeaForecastCode {
400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401 f.write_str(self.as_str())
402 }
403}
404#[derive(Debug, Clone, PartialEq, Eq, Default)]
406#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
407pub enum NeaLightningType {
408 #[cfg_attr(feature = "serde", serde(rename = "C"))]
409 CloudToCloud,
410 #[cfg_attr(feature = "serde", serde(rename = "G"))]
411 CloudToGround,
412 #[default]
413 #[cfg_attr(feature = "serde", serde(other))]
414 Unknown,
415}
416impl NeaLightningType {
417 pub const fn as_str(&self) -> &'static str {
418 match self {
419 Self::CloudToCloud => "C",
420 Self::CloudToGround => "G",
421 Self::Unknown => "",
422 }
423 }
424}
425impl AsRef<str> for NeaLightningType {
426 fn as_ref(&self) -> &str {
427 self.as_str()
428 }
429}
430impl fmt::Display for NeaLightningType {
431 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
432 f.write_str(self.as_str())
433 }
434}
435#[derive(Debug, Clone, PartialEq, Eq, Default)]
437#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
438pub enum NeaForecastText {
439 Fair,
440 #[cfg_attr(feature = "serde", serde(rename = "Fair (Day)"))]
441 FairDay,
442 #[cfg_attr(feature = "serde", serde(rename = "Fair (Night)"))]
443 FairNight,
444 #[cfg_attr(feature = "serde", serde(rename = "Fair and Warm"))]
445 FairAndWarm,
446 #[cfg_attr(feature = "serde", serde(rename = "Partly Cloudy"))]
447 PartlyCloudy,
448 #[cfg_attr(feature = "serde", serde(rename = "Partly Cloudy (Day)"))]
449 PartlyCloudyDay,
450 #[cfg_attr(feature = "serde", serde(rename = "Partly Cloudy (Night)"))]
451 PartlyCloudyNight,
452 Cloudy,
453 Hazy,
454 #[cfg_attr(feature = "serde", serde(rename = "Slightly Hazy"))]
455 SlightlyHazy,
456 Windy,
457 Mist,
458 Fog,
459 #[cfg_attr(feature = "serde", serde(rename = "Light Rain"))]
460 LightRain,
461 #[cfg_attr(feature = "serde", serde(rename = "Moderate Rain"))]
462 ModerateRain,
463 #[cfg_attr(feature = "serde", serde(rename = "Heavy Rain"))]
464 HeavyRain,
465 #[cfg_attr(feature = "serde", serde(rename = "Passing Showers"))]
466 PassingShowers,
467 #[cfg_attr(feature = "serde", serde(rename = "Light Showers"))]
468 LightShowers,
469 Showers,
470 #[cfg_attr(feature = "serde", serde(rename = "Heavy Showers"))]
471 HeavyShowers,
472 #[cfg_attr(feature = "serde", serde(rename = "Thundery Showers"))]
473 ThunderyShowers,
474 #[cfg_attr(feature = "serde", serde(rename = "Heavy Thundery Showers"))]
475 HeavyThunderyShowers,
476 #[cfg_attr(
477 feature = "serde",
478 serde(rename = "Heavy Thundery Showers with Gusty Winds")
479 )]
480 HeavyThunderyShowersWithGustyWinds,
481 #[default]
482 #[cfg_attr(feature = "serde", serde(other))]
483 Unknown,
484}
485impl NeaForecastText {
486 pub const fn as_str(&self) -> &'static str {
487 match self {
488 Self::Fair => "Fair",
489 Self::FairDay => "Fair (Day)",
490 Self::FairNight => "Fair (Night)",
491 Self::FairAndWarm => "Fair and Warm",
492 Self::PartlyCloudy => "Partly Cloudy",
493 Self::PartlyCloudyDay => "Partly Cloudy (Day)",
494 Self::PartlyCloudyNight => "Partly Cloudy (Night)",
495 Self::Cloudy => "Cloudy",
496 Self::Hazy => "Hazy",
497 Self::SlightlyHazy => "Slightly Hazy",
498 Self::Windy => "Windy",
499 Self::Mist => "Mist",
500 Self::Fog => "Fog",
501 Self::LightRain => "Light Rain",
502 Self::ModerateRain => "Moderate Rain",
503 Self::HeavyRain => "Heavy Rain",
504 Self::PassingShowers => "Passing Showers",
505 Self::LightShowers => "Light Showers",
506 Self::Showers => "Showers",
507 Self::HeavyShowers => "Heavy Showers",
508 Self::ThunderyShowers => "Thundery Showers",
509 Self::HeavyThunderyShowers => "Heavy Thundery Showers",
510 Self::HeavyThunderyShowersWithGustyWinds => "Heavy Thundery Showers with Gusty Winds",
511 Self::Unknown => "",
512 }
513 }
514}
515impl AsRef<str> for NeaForecastText {
516 fn as_ref(&self) -> &str {
517 self.as_str()
518 }
519}
520impl fmt::Display for NeaForecastText {
521 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
522 f.write_str(self.as_str())
523 }
524}
525#[derive(Debug, Clone, PartialEq, Eq, Default)]
527#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
528pub enum NeaDayOfWeek {
529 Monday,
530 Tuesday,
531 Wednesday,
532 Thursday,
533 Friday,
534 Saturday,
535 Sunday,
536 #[default]
537 #[cfg_attr(feature = "serde", serde(other))]
538 Unknown,
539}
540impl NeaDayOfWeek {
541 pub const fn as_str(&self) -> &'static str {
542 match self {
543 Self::Monday => "Monday",
544 Self::Tuesday => "Tuesday",
545 Self::Wednesday => "Wednesday",
546 Self::Thursday => "Thursday",
547 Self::Friday => "Friday",
548 Self::Saturday => "Saturday",
549 Self::Sunday => "Sunday",
550 Self::Unknown => "",
551 }
552 }
553}
554impl AsRef<str> for NeaDayOfWeek {
555 fn as_ref(&self) -> &str {
556 self.as_str()
557 }
558}
559impl fmt::Display for NeaDayOfWeek {
560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
561 f.write_str(self.as_str())
562 }
563}
564#[derive(Debug, Clone, PartialEq, Eq, Default)]
566#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
567pub enum NeaInvalidParamsErrorMsg {
568 #[cfg_attr(
569 feature = "serde",
570 serde(
571 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)."
572 )
573 )]
574 InvalidDateFormat,
575 #[cfg_attr(feature = "serde", serde(rename = "Invalid pagination token."))]
576 InvalidPaginationToken,
577 #[default]
578 #[cfg_attr(feature = "serde", serde(other))]
579 Unknown,
580}
581impl NeaInvalidParamsErrorMsg {
582 pub const fn as_str(&self) -> &'static str {
583 match self {
584 Self::InvalidDateFormat => {
585 "Invalid date format. Date format must be YYYY-MM-DD (2024-06-01) or YYYY-MM-DDTHH:mm:ss (2024-06-01T08:30:00)."
586 }
587 Self::InvalidPaginationToken => "Invalid pagination token.",
588 Self::Unknown => "",
589 }
590 }
591}
592impl AsRef<str> for NeaInvalidParamsErrorMsg {
593 fn as_ref(&self) -> &str {
594 self.as_str()
595 }
596}
597impl fmt::Display for NeaInvalidParamsErrorMsg {
598 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
599 f.write_str(self.as_str())
600 }
601}
602#[derive(Debug, Clone, PartialEq, Eq, Default)]
604#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
605pub enum NeaWeatherSubApi {
606 #[cfg_attr(feature = "serde", serde(rename = "lightning"))]
607 Lightning,
608 #[cfg_attr(feature = "serde", serde(rename = "wbgt"))]
609 WetBulbGlobeTemperature,
610 #[default]
611 #[cfg_attr(feature = "serde", serde(other))]
612 Unknown,
613}
614impl NeaWeatherSubApi {
615 pub const fn as_str(&self) -> &'static str {
616 match self {
617 Self::Lightning => "lightning",
618 Self::WetBulbGlobeTemperature => "wbgt",
619 Self::Unknown => "",
620 }
621 }
622}
623impl AsRef<str> for NeaWeatherSubApi {
624 fn as_ref(&self) -> &str {
625 self.as_str()
626 }
627}
628impl fmt::Display for NeaWeatherSubApi {
629 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630 f.write_str(self.as_str())
631 }
632}
633#[nutype::nutype(
635 validate(regex = "^S[0-9]{2,3}$", len_char_min = 3, len_char_max = 4),
636 derive(
637 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, AsRef, Deref, TryFrom, Into, Display, Hash
638 ),
639 cfg_attr(feature = "serde", derive(Serialize, Deserialize))
640)]
641pub struct NeaStationId(String);
642#[derive(Debug, Clone, PartialEq)]
644#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
645pub struct NeaStationLocation {
646 pub latitude: NeaLatitude,
648 pub longitude: NeaLongitude,
650}
651#[derive(Debug, Clone, PartialEq, Eq, Default)]
653#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
654pub enum NeaWindDirection16 {
655 N,
656 #[cfg_attr(feature = "serde", serde(rename = "NNE"))]
657 Nne,
658 #[cfg_attr(feature = "serde", serde(rename = "NE"))]
659 Ne,
660 #[cfg_attr(feature = "serde", serde(rename = "ENE"))]
661 Ene,
662 E,
663 #[cfg_attr(feature = "serde", serde(rename = "ESE"))]
664 Ese,
665 #[cfg_attr(feature = "serde", serde(rename = "SE"))]
666 Se,
667 #[cfg_attr(feature = "serde", serde(rename = "SSE"))]
668 Sse,
669 S,
670 #[cfg_attr(feature = "serde", serde(rename = "SSW"))]
671 Ssw,
672 #[cfg_attr(feature = "serde", serde(rename = "SW"))]
673 Sw,
674 #[cfg_attr(feature = "serde", serde(rename = "WSW"))]
675 Wsw,
676 W,
677 #[cfg_attr(feature = "serde", serde(rename = "WNW"))]
678 Wnw,
679 #[cfg_attr(feature = "serde", serde(rename = "NW"))]
680 Nw,
681 #[cfg_attr(feature = "serde", serde(rename = "NNW"))]
682 Nnw,
683 #[default]
684 #[cfg_attr(feature = "serde", serde(other))]
685 Unknown,
686}
687impl NeaWindDirection16 {
688 pub const fn as_str(&self) -> &'static str {
689 match self {
690 Self::N => "N",
691 Self::Nne => "NNE",
692 Self::Ne => "NE",
693 Self::Ene => "ENE",
694 Self::E => "E",
695 Self::Ese => "ESE",
696 Self::Se => "SE",
697 Self::Sse => "SSE",
698 Self::S => "S",
699 Self::Ssw => "SSW",
700 Self::Sw => "SW",
701 Self::Wsw => "WSW",
702 Self::W => "W",
703 Self::Wnw => "WNW",
704 Self::Nw => "NW",
705 Self::Nnw => "NNW",
706 Self::Unknown => "",
707 }
708 }
709}
710impl AsRef<str> for NeaWindDirection16 {
711 fn as_ref(&self) -> &str {
712 self.as_str()
713 }
714}
715impl fmt::Display for NeaWindDirection16 {
716 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
717 f.write_str(self.as_str())
718 }
719}
720pub type NeaStringLatitude = f64;
722pub type NeaStringLongitude = f64;
724#[derive(Debug, Clone, PartialEq)]
725#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
726pub struct NeaWeatherStation {
727 pub id: NeaStationId,
729 #[cfg_attr(feature = "serde", serde(rename = "deviceId"))]
731 pub device_id: NeaStationId,
732 pub name: String,
734 pub location: NeaStationLocation,
736}
737#[derive(Debug, Clone, PartialEq)]
738#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
739pub struct NeaReadingSnapshot {
740 #[cfg_attr(
742 feature = "serde",
743 serde(with = "satay_runtime::serde_string::as_offset_datetime")
744 )]
745 pub timestamp: satay_runtime::OffsetDateTime,
746 pub data: Vec<NeaStationReading>,
747}
748#[derive(Debug, Clone, PartialEq)]
749#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
750pub struct NeaStationReading {
751 #[cfg_attr(feature = "serde", serde(rename = "stationId"))]
753 pub station_id: NeaStationId,
754 pub value: f64,
755}
756#[derive(Debug, Clone, PartialEq)]
758#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
759pub struct NeaHumidityRange {
760 pub low: NeaHumidityPercent,
762 pub high: NeaHumidityPercent,
764 pub unit: NeaMeasurementUnit,
766}
767#[derive(Debug, Clone, PartialEq)]
769#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
770pub struct NeaTemperatureRange {
771 pub low: NeaTemperatureCelsius,
773 pub high: NeaTemperatureCelsius,
775 pub unit: NeaMeasurementUnit,
777}
778#[derive(Debug, Clone, PartialEq)]
780#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
781pub struct NeaWindSpeedRange {
782 pub low: NeaWindSpeedKmh,
784 pub high: NeaWindSpeedKmh,
786}
787#[derive(Debug, Clone, PartialEq)]
788#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
789pub struct NeaOutlookWind {
790 pub speed: NeaWindSpeedRange,
792 pub direction: NeaWindDirection16,
794}
795#[derive(Debug, Clone, PartialEq)]
796#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
797pub struct NeaMssForecast {
798 pub code: NeaForecastCode,
800 pub text: NeaForecastText,
802}
803#[derive(Debug, Clone, PartialEq)]
804#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
805pub struct NeaGeoPoint {
806 pub latitude: NeaLatitude,
808 pub longitude: NeaLongitude,
810}
811#[derive(Debug, Clone, PartialEq)]
812#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
813pub struct AirTemperatureData {
814 pub stations: Vec<NeaWeatherStation>,
815 pub readings: Vec<NeaReadingSnapshot>,
816 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
818 pub reading_type: String,
819 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
821 pub reading_unit: NeaMeasurementUnit,
822 #[cfg_attr(
824 feature = "serde",
825 serde(
826 rename = "paginationToken",
827 default,
828 skip_serializing_if = "Option::is_none"
829 )
830 )]
831 pub pagination_token: Option<String>,
832}
833#[derive(Debug, Clone, PartialEq)]
834#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
835pub struct RelativeHumidityData {
836 pub stations: Vec<NeaWeatherStation>,
837 pub readings: Vec<NeaReadingSnapshot>,
838 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
840 pub reading_type: String,
841 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
843 pub reading_unit: NeaMeasurementUnit,
844 #[cfg_attr(
846 feature = "serde",
847 serde(
848 rename = "paginationToken",
849 default,
850 skip_serializing_if = "Option::is_none"
851 )
852 )]
853 pub pagination_token: Option<String>,
854}
855#[derive(Debug, Clone, PartialEq)]
856#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
857pub struct WindSpeedData {
858 pub stations: Vec<NeaWeatherStation>,
859 pub readings: Vec<NeaReadingSnapshot>,
860 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
862 pub reading_type: String,
863 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
865 pub reading_unit: NeaMeasurementUnit,
866 #[cfg_attr(
868 feature = "serde",
869 serde(
870 rename = "paginationToken",
871 default,
872 skip_serializing_if = "Option::is_none"
873 )
874 )]
875 pub pagination_token: Option<String>,
876}
877#[derive(Debug, Clone, PartialEq)]
878#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
879pub struct WindDirectionData {
880 pub stations: Vec<NeaWeatherStation>,
881 pub readings: Vec<NeaReadingSnapshot>,
882 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
884 pub reading_type: String,
885 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
887 pub reading_unit: NeaMeasurementUnit,
888 #[cfg_attr(
890 feature = "serde",
891 serde(
892 rename = "paginationToken",
893 default,
894 skip_serializing_if = "Option::is_none"
895 )
896 )]
897 pub pagination_token: Option<String>,
898}
899#[derive(Debug, Clone, PartialEq)]
900#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
901pub struct RainfallData {
902 pub stations: Vec<NeaWeatherStation>,
903 pub readings: Vec<NeaReadingSnapshot>,
904 #[cfg_attr(feature = "serde", serde(rename = "readingType"))]
906 pub reading_type: String,
907 #[cfg_attr(feature = "serde", serde(rename = "readingUnit"))]
909 pub reading_unit: NeaMeasurementUnit,
910 #[cfg_attr(
912 feature = "serde",
913 serde(
914 rename = "paginationToken",
915 default,
916 skip_serializing_if = "Option::is_none"
917 )
918 )]
919 pub pagination_token: Option<String>,
920}
921#[derive(Debug, Clone, PartialEq)]
923#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
924pub struct FourDayOutlookData {
925 pub records: Vec<FourDayOutlookDay>,
926}
927#[derive(Debug, Clone, PartialEq)]
928#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
929pub struct FourDayOutlookDay {
930 #[cfg_attr(
932 feature = "serde",
933 serde(with = "satay_runtime::serde_string::as_date")
934 )]
935 pub date: satay_runtime::Date,
936 #[cfg_attr(
938 feature = "serde",
939 serde(
940 rename = "updatedTimestamp",
941 with = "satay_runtime::serde_string::as_offset_datetime"
942 )
943 )]
944 pub updated_timestamp: satay_runtime::OffsetDateTime,
945 #[cfg_attr(
947 feature = "serde",
948 serde(with = "satay_runtime::serde_string::as_offset_datetime")
949 )]
950 pub timestamp: satay_runtime::OffsetDateTime,
951 pub forecasts: Vec<FourDayOutlookPeriod>,
953}
954#[derive(Debug, Clone, PartialEq)]
955#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
956pub struct FourDayOutlookPeriod {
957 #[cfg_attr(
959 feature = "serde",
960 serde(with = "satay_runtime::serde_string::as_offset_datetime")
961 )]
962 pub timestamp: satay_runtime::OffsetDateTime,
963 pub temperature: NeaTemperatureRange,
965 #[cfg_attr(feature = "serde", serde(rename = "relativeHumidity"))]
967 pub relative_humidity: NeaHumidityRange,
968 pub forecast: NeaOutlookForecastDetail,
969 pub day: NeaDayOfWeek,
971 pub wind: NeaOutlookWind,
972}
973#[derive(Debug, Clone, PartialEq)]
974#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
975pub struct NeaOutlookForecastDetail {
976 pub summary: String,
977 pub code: NeaForecastCode,
979 pub text: NeaForecastText,
981}
982#[derive(Debug, Clone, PartialEq)]
983#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
984pub struct TwentyFourHrForecastData {
985 #[cfg_attr(
986 feature = "serde",
987 serde(default, skip_serializing_if = "Option::is_none")
988 )]
989 pub area_metadata: Option<Vec<NeaForecastArea>>,
990 pub records: Vec<TwentyFourHrForecastDay>,
991 #[cfg_attr(
993 feature = "serde",
994 serde(
995 rename = "paginationToken",
996 default,
997 skip_serializing_if = "Option::is_none"
998 )
999 )]
1000 pub pagination_token: Option<String>,
1001}
1002#[derive(Debug, Clone, PartialEq)]
1003#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1004pub struct TwentyFourHrForecastDay {
1005 #[cfg_attr(
1007 feature = "serde",
1008 serde(with = "satay_runtime::serde_string::as_date")
1009 )]
1010 pub date: satay_runtime::Date,
1011 #[cfg_attr(
1013 feature = "serde",
1014 serde(
1015 rename = "updatedTimestamp",
1016 with = "satay_runtime::serde_string::as_offset_datetime"
1017 )
1018 )]
1019 pub updated_timestamp: satay_runtime::OffsetDateTime,
1020 #[cfg_attr(
1022 feature = "serde",
1023 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1024 )]
1025 pub timestamp: satay_runtime::OffsetDateTime,
1026 pub general: TwentyFourHrForecastGeneral,
1028 pub periods: Vec<TwentyFourHrForecastPeriod>,
1030}
1031#[derive(Debug, Clone, PartialEq)]
1033#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1034pub struct TwentyFourHrForecastGeneral {
1035 #[cfg_attr(feature = "serde", serde(rename = "validPeriod"))]
1037 pub valid_period: NeaValidPeriod,
1038 pub temperature: NeaTemperatureRange,
1040 #[cfg_attr(feature = "serde", serde(rename = "relativeHumidity"))]
1042 pub relative_humidity: NeaHumidityRange,
1043 pub forecast: NeaMssForecast,
1044 pub wind: NeaOutlookWind,
1045}
1046#[derive(Debug, Clone, PartialEq)]
1047#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1048pub struct TwentyFourHrForecastPeriod {
1049 #[cfg_attr(feature = "serde", serde(rename = "timePeriod"))]
1051 pub time_period: NeaValidPeriod,
1052 pub regions: TwentyFourHrRegionalForecast,
1053}
1054#[derive(Debug, Clone, PartialEq)]
1055#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1056pub struct TwentyFourHrRegionalForecast {
1057 pub west: NeaMssForecast,
1058 pub east: NeaMssForecast,
1059 pub central: NeaMssForecast,
1060 pub north: NeaMssForecast,
1061 pub south: NeaMssForecast,
1062}
1063#[derive(Debug, Clone, PartialEq)]
1064#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1065pub struct TwoHrForecastData {
1066 pub area_metadata: Vec<NeaForecastArea>,
1067 pub items: Vec<TwoHrForecastSnapshot>,
1068 #[cfg_attr(
1070 feature = "serde",
1071 serde(
1072 rename = "paginationToken",
1073 default,
1074 skip_serializing_if = "Option::is_none"
1075 )
1076 )]
1077 pub pagination_token: Option<String>,
1078}
1079#[derive(Debug, Clone, PartialEq)]
1080#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1081pub struct NeaForecastArea {
1082 pub name: String,
1084 pub label_location: NeaGeoPoint,
1085}
1086#[derive(Debug, Clone, PartialEq)]
1087#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1088pub struct TwoHrForecastSnapshot {
1089 #[cfg_attr(
1091 feature = "serde",
1092 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1093 )]
1094 pub update_timestamp: satay_runtime::OffsetDateTime,
1095 #[cfg_attr(
1097 feature = "serde",
1098 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1099 )]
1100 pub timestamp: satay_runtime::OffsetDateTime,
1101 pub valid_period: NeaValidPeriod,
1103 pub forecasts: Vec<TwoHrAreaForecast>,
1105}
1106#[derive(Debug, Clone, PartialEq)]
1107#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1108pub struct TwoHrAreaForecast {
1109 pub area: String,
1110 pub forecast: NeaForecastText,
1112}
1113#[derive(Debug, Clone, PartialEq)]
1115#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1116pub struct NeaValidPeriod {
1117 #[cfg_attr(
1119 feature = "serde",
1120 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1121 )]
1122 pub start: satay_runtime::OffsetDateTime,
1123 #[cfg_attr(
1125 feature = "serde",
1126 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1127 )]
1128 pub end: satay_runtime::OffsetDateTime,
1129 pub text: String,
1130}
1131#[derive(Debug, Clone, PartialEq)]
1132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1133pub struct PsiData {
1134 #[cfg_attr(feature = "serde", serde(rename = "regionMetadata"))]
1135 pub region_metadata: Vec<NeaRegionMetadata>,
1136 pub items: Vec<PsiSnapshot>,
1137 #[cfg_attr(
1139 feature = "serde",
1140 serde(
1141 rename = "paginationToken",
1142 default,
1143 skip_serializing_if = "Option::is_none"
1144 )
1145 )]
1146 pub pagination_token: Option<String>,
1147}
1148#[derive(Debug, Clone, PartialEq)]
1149#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1150pub struct PsiSnapshot {
1151 #[cfg_attr(
1153 feature = "serde",
1154 serde(with = "satay_runtime::serde_string::as_date")
1155 )]
1156 pub date: satay_runtime::Date,
1157 #[cfg_attr(
1159 feature = "serde",
1160 serde(
1161 rename = "updatedTimestamp",
1162 with = "satay_runtime::serde_string::as_offset_datetime"
1163 )
1164 )]
1165 pub updated_timestamp: satay_runtime::OffsetDateTime,
1166 #[cfg_attr(
1168 feature = "serde",
1169 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1170 )]
1171 pub timestamp: satay_runtime::OffsetDateTime,
1172 pub readings: PsiReadings,
1174}
1175#[derive(Debug, Clone, PartialEq)]
1177#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1178pub struct PsiReadings {
1179 pub co_sub_index: PsiCoSubIndexRegional,
1181 pub so2_twenty_four_hourly: PsiSo2TwentyFourHourRegional,
1183 pub so2_sub_index: PsiSo2SubIndexRegional,
1185 #[cfg_attr(
1187 feature = "serde",
1188 serde(default, skip_serializing_if = "Option::is_none")
1189 )]
1190 pub psi_three_hourly: Option<PsiThreeHourRegional>,
1191 pub co_eight_hour_max: PsiCoEightHourMaxRegional,
1193 pub no2_one_hour_max: PsiNo2OneHourMaxRegional,
1195 pub pm10_sub_index: PsiPm10SubIndexRegional,
1197 pub pm25_sub_index: PsiPm25SubIndexRegional,
1199 pub o3_eight_hour_max: PsiO3EightHourMaxRegional,
1201 pub psi_twenty_four_hourly: PsiTwentyFourHourRegional,
1203 pub o3_sub_index: PsiO3SubIndexRegional,
1205 pub pm25_twenty_four_hourly: PsiPm25TwentyFourHourRegional,
1207 pub pm10_twenty_four_hourly: PsiPm10TwentyFourHourRegional,
1209}
1210#[derive(Debug, Clone, PartialEq)]
1211#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1212pub struct NeaRegionMetadata {
1213 pub name: NeaRegionMetadataName,
1215 #[cfg_attr(feature = "serde", serde(rename = "labelLocation"))]
1216 pub label_location: NeaGeoPoint,
1217}
1218#[derive(Debug, Clone, PartialEq)]
1220#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1221pub struct PsiCoEightHourMaxRegional {
1222 pub east: NeaRegionalReading,
1224 pub west: NeaRegionalReading,
1226 pub north: NeaRegionalReading,
1228 pub south: NeaRegionalReading,
1230 pub central: NeaRegionalReading,
1232}
1233#[derive(Debug, Clone, PartialEq)]
1235#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1236pub struct PsiCoSubIndexRegional {
1237 pub east: NeaRegionalReading,
1239 pub west: NeaRegionalReading,
1241 pub north: NeaRegionalReading,
1243 pub south: NeaRegionalReading,
1245 pub central: NeaRegionalReading,
1247}
1248#[derive(Debug, Clone, PartialEq)]
1250#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1251pub struct PsiNo2OneHourMaxRegional {
1252 pub east: NeaRegionalReading,
1254 pub west: NeaRegionalReading,
1256 pub north: NeaRegionalReading,
1258 pub south: NeaRegionalReading,
1260 pub central: NeaRegionalReading,
1262}
1263#[derive(Debug, Clone, PartialEq)]
1265#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1266pub struct PsiO3EightHourMaxRegional {
1267 pub east: NeaRegionalReading,
1269 pub west: NeaRegionalReading,
1271 pub north: NeaRegionalReading,
1273 pub south: NeaRegionalReading,
1275 pub central: NeaRegionalReading,
1277}
1278#[derive(Debug, Clone, PartialEq)]
1280#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1281pub struct PsiO3SubIndexRegional {
1282 pub east: NeaRegionalReading,
1284 pub west: NeaRegionalReading,
1286 pub north: NeaRegionalReading,
1288 pub south: NeaRegionalReading,
1290 pub central: NeaRegionalReading,
1292}
1293#[derive(Debug, Clone, PartialEq)]
1295#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1296pub struct PsiPm10SubIndexRegional {
1297 pub east: NeaRegionalReading,
1299 pub west: NeaRegionalReading,
1301 pub north: NeaRegionalReading,
1303 pub south: NeaRegionalReading,
1305 pub central: NeaRegionalReading,
1307}
1308#[derive(Debug, Clone, PartialEq)]
1310#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1311pub struct PsiPm10TwentyFourHourRegional {
1312 pub east: NeaRegionalReading,
1314 pub west: NeaRegionalReading,
1316 pub north: NeaRegionalReading,
1318 pub south: NeaRegionalReading,
1320 pub central: NeaRegionalReading,
1322}
1323#[derive(Debug, Clone, PartialEq)]
1325#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1326pub struct PsiPm25SubIndexRegional {
1327 pub east: NeaRegionalReading,
1329 pub west: NeaRegionalReading,
1331 pub north: NeaRegionalReading,
1333 pub south: NeaRegionalReading,
1335 pub central: NeaRegionalReading,
1337}
1338#[derive(Debug, Clone, PartialEq)]
1340#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1341pub struct PsiPm25TwentyFourHourRegional {
1342 pub east: NeaRegionalReading,
1344 pub west: NeaRegionalReading,
1346 pub north: NeaRegionalReading,
1348 pub south: NeaRegionalReading,
1350 pub central: NeaRegionalReading,
1352}
1353#[derive(Debug, Clone, PartialEq)]
1355#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1356pub struct PsiThreeHourRegional {
1357 #[cfg_attr(
1359 feature = "serde",
1360 serde(default, skip_serializing_if = "Option::is_none")
1361 )]
1362 pub east: Option<NeaRegionalReading>,
1363 #[cfg_attr(
1365 feature = "serde",
1366 serde(default, skip_serializing_if = "Option::is_none")
1367 )]
1368 pub west: Option<NeaRegionalReading>,
1369 #[cfg_attr(
1371 feature = "serde",
1372 serde(default, skip_serializing_if = "Option::is_none")
1373 )]
1374 pub north: Option<NeaRegionalReading>,
1375 #[cfg_attr(
1377 feature = "serde",
1378 serde(default, skip_serializing_if = "Option::is_none")
1379 )]
1380 pub south: Option<NeaRegionalReading>,
1381 #[cfg_attr(
1383 feature = "serde",
1384 serde(default, skip_serializing_if = "Option::is_none")
1385 )]
1386 pub central: Option<NeaRegionalReading>,
1387}
1388#[derive(Debug, Clone, PartialEq)]
1390#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1391pub struct PsiTwentyFourHourRegional {
1392 pub east: NeaRegionalReading,
1394 pub west: NeaRegionalReading,
1396 pub north: NeaRegionalReading,
1398 pub south: NeaRegionalReading,
1400 pub central: NeaRegionalReading,
1402}
1403#[derive(Debug, Clone, PartialEq)]
1405#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1406pub struct PsiSo2SubIndexRegional {
1407 pub east: NeaRegionalReading,
1409 pub west: NeaRegionalReading,
1411 pub north: NeaRegionalReading,
1413 pub south: NeaRegionalReading,
1415 pub central: NeaRegionalReading,
1417}
1418#[derive(Debug, Clone, PartialEq)]
1420#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1421pub struct PsiSo2TwentyFourHourRegional {
1422 pub east: NeaRegionalReading,
1424 pub west: NeaRegionalReading,
1426 pub north: NeaRegionalReading,
1428 pub south: NeaRegionalReading,
1430 pub central: NeaRegionalReading,
1432}
1433#[derive(Debug, Clone, PartialEq)]
1434#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1435pub struct Pm25Data {
1436 #[cfg_attr(feature = "serde", serde(rename = "regionMetadata"))]
1437 pub region_metadata: Vec<NeaRegionMetadata>,
1438 pub items: Vec<Pm25Snapshot>,
1439 #[cfg_attr(
1441 feature = "serde",
1442 serde(
1443 rename = "paginationToken",
1444 default,
1445 skip_serializing_if = "Option::is_none"
1446 )
1447 )]
1448 pub pagination_token: Option<String>,
1449}
1450#[derive(Debug, Clone, PartialEq)]
1451#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1452pub struct Pm25Snapshot {
1453 #[cfg_attr(
1455 feature = "serde",
1456 serde(with = "satay_runtime::serde_string::as_date")
1457 )]
1458 pub date: satay_runtime::Date,
1459 #[cfg_attr(
1461 feature = "serde",
1462 serde(
1463 rename = "updatedTimestamp",
1464 with = "satay_runtime::serde_string::as_offset_datetime"
1465 )
1466 )]
1467 pub updated_timestamp: satay_runtime::OffsetDateTime,
1468 #[cfg_attr(
1470 feature = "serde",
1471 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1472 )]
1473 pub timestamp: satay_runtime::OffsetDateTime,
1474 pub readings: Pm25Readings,
1476}
1477#[derive(Debug, Clone, PartialEq)]
1479#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1480pub struct Pm25Readings {
1481 pub pm25_one_hourly: Pm25OneHourRegional,
1482}
1483#[derive(Debug, Clone, PartialEq)]
1484#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1485pub struct Pm25OneHourRegional {
1486 pub east: NeaPm25HourlyReading,
1488 pub west: NeaPm25HourlyReading,
1490 pub north: NeaPm25HourlyReading,
1492 pub south: NeaPm25HourlyReading,
1494 pub central: NeaPm25HourlyReading,
1496}
1497#[derive(Debug, Clone, PartialEq)]
1498#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1499pub struct UvData {
1500 pub records: Vec<UvDayRecord>,
1501 #[cfg_attr(
1503 feature = "serde",
1504 serde(
1505 rename = "paginationToken",
1506 default,
1507 skip_serializing_if = "Option::is_none"
1508 )
1509 )]
1510 pub pagination_token: Option<String>,
1511}
1512#[derive(Debug, Clone, PartialEq)]
1513#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1514pub struct UvDayRecord {
1515 pub index: Vec<UvHourlyIndex>,
1516 #[cfg_attr(
1518 feature = "serde",
1519 serde(with = "satay_runtime::serde_string::as_date")
1520 )]
1521 pub date: satay_runtime::Date,
1522 #[cfg_attr(
1524 feature = "serde",
1525 serde(
1526 rename = "updatedTimestamp",
1527 with = "satay_runtime::serde_string::as_offset_datetime"
1528 )
1529 )]
1530 pub updated_timestamp: satay_runtime::OffsetDateTime,
1531 #[cfg_attr(
1533 feature = "serde",
1534 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1535 )]
1536 pub timestamp: satay_runtime::OffsetDateTime,
1537}
1538#[derive(Debug, Clone, PartialEq)]
1540#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1541pub struct UvHourlyIndex {
1542 #[cfg_attr(
1544 feature = "serde",
1545 serde(with = "satay_runtime::serde_string::as_offset_datetime")
1546 )]
1547 pub hour: satay_runtime::OffsetDateTime,
1548 pub value: NeaUvIndex,
1550}
1551#[derive(Debug, Clone, PartialEq)]
1552#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1553pub struct WeatherSubApiData {
1554 #[cfg_attr(
1555 feature = "serde",
1556 serde(default, skip_serializing_if = "Option::is_none")
1557 )]
1558 pub records: Option<Vec<WeatherSubApiDayRecord>>,
1559 #[cfg_attr(
1561 feature = "serde",
1562 serde(
1563 rename = "paginationToken",
1564 default,
1565 skip_serializing_if = "Option::is_none"
1566 )
1567 )]
1568 pub pagination_token: Option<String>,
1569}
1570#[derive(Debug, Clone, PartialEq)]
1571#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1572pub struct WeatherSubApiDayRecord {
1573 #[cfg_attr(
1575 feature = "serde",
1576 serde(
1577 with = "satay_runtime::serde_string::as_offset_datetime::option",
1578 default,
1579 skip_serializing_if = "Option::is_none"
1580 )
1581 )]
1582 pub datetime: Option<satay_runtime::OffsetDateTime>,
1583 #[cfg_attr(
1585 feature = "serde",
1586 serde(default, skip_serializing_if = "Option::is_none")
1587 )]
1588 pub item: Option<WeatherSubApiObservation>,
1589 #[cfg_attr(
1591 feature = "serde",
1592 serde(
1593 rename = "updatedTimestamp",
1594 with = "satay_runtime::serde_string::as_offset_datetime::option",
1595 default,
1596 skip_serializing_if = "Option::is_none"
1597 )
1598 )]
1599 pub updated_timestamp: Option<satay_runtime::OffsetDateTime>,
1600}
1601#[derive(Debug, Clone, PartialEq)]
1603#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1604pub struct WeatherSubApiObservation {
1605 #[cfg_attr(
1607 feature = "serde",
1608 serde(rename = "type", default, skip_serializing_if = "Option::is_none")
1609 )]
1610 pub type_: Option<String>,
1611 #[cfg_attr(
1613 feature = "serde",
1614 serde(
1615 rename = "isStationData",
1616 default,
1617 skip_serializing_if = "Option::is_none"
1618 )
1619 )]
1620 pub is_station_data: Option<bool>,
1621 #[cfg_attr(
1622 feature = "serde",
1623 serde(default, skip_serializing_if = "Option::is_none")
1624 )]
1625 pub readings: Option<Vec<WeatherSubApiLightningReading>>,
1626}
1627#[derive(Debug, Clone, PartialEq)]
1628#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1629pub struct WeatherSubApiLightningReading {
1630 #[cfg_attr(
1632 feature = "serde",
1633 serde(default, skip_serializing_if = "Option::is_none")
1634 )]
1635 pub location: Option<NeaLightningGeoPoint>,
1636 #[cfg_attr(
1638 feature = "serde",
1639 serde(
1640 with = "satay_runtime::serde_string::as_offset_datetime::option",
1641 default,
1642 skip_serializing_if = "Option::is_none"
1643 )
1644 )]
1645 pub datetime: Option<satay_runtime::OffsetDateTime>,
1646 #[cfg_attr(
1648 feature = "serde",
1649 serde(default, skip_serializing_if = "Option::is_none")
1650 )]
1651 pub text: Option<String>,
1652 #[cfg_attr(
1654 feature = "serde",
1655 serde(rename = "type", default, skip_serializing_if = "Option::is_none")
1656 )]
1657 pub type_: Option<NeaLightningType>,
1658 #[cfg_attr(
1660 feature = "serde",
1661 serde(default, skip_serializing_if = "Option::is_none")
1662 )]
1663 pub station: Option<NeaWbgtStation>,
1664 #[cfg_attr(
1666 feature = "serde",
1667 serde(
1668 with = "satay_runtime::serde_string::as_f64::option",
1669 default,
1670 skip_serializing_if = "Option::is_none"
1671 )
1672 )]
1673 pub wbgt: Option<f64>,
1674 #[cfg_attr(
1676 feature = "serde",
1677 serde(
1678 rename = "heatStress",
1679 default,
1680 skip_serializing_if = "Option::is_none"
1681 )
1682 )]
1683 pub heat_stress: Option<NeaHeatStressLevel>,
1684}
1685#[derive(Debug, Clone, PartialEq)]
1686#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1687pub struct WeatherSubApiInvalidParamsError {
1688 #[cfg_attr(
1689 feature = "serde",
1690 serde(default, skip_serializing_if = "Option::is_none")
1691 )]
1692 pub code: Option<f64>,
1693 #[cfg_attr(
1694 feature = "serde",
1695 serde(default, skip_serializing_if = "Option::is_none")
1696 )]
1697 pub name: Option<String>,
1698 #[cfg_attr(
1699 feature = "serde",
1700 serde(rename = "errorMsg", default, skip_serializing_if = "Option::is_none")
1701 )]
1702 pub error_msg: Option<String>,
1703}
1704#[derive(Debug, Clone, PartialEq, Eq, Default)]
1706#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1707pub enum NeaMeasurementUnit {
1708 #[cfg_attr(feature = "serde", serde(rename = "deg C"))]
1709 DegC,
1710 #[cfg_attr(feature = "serde", serde(rename = "Degrees Celsius"))]
1711 DegreesCelsius,
1712 Percentage,
1713 #[cfg_attr(feature = "serde", serde(rename = "percentage"))]
1714 PercentLower,
1715 #[cfg_attr(feature = "serde", serde(rename = "knots"))]
1716 Knots,
1717 #[cfg_attr(feature = "serde", serde(rename = "degrees"))]
1718 Degrees,
1719 #[cfg_attr(feature = "serde", serde(rename = "mm"))]
1720 Millimeters,
1721 #[default]
1722 #[cfg_attr(feature = "serde", serde(other))]
1723 Unknown,
1724}
1725impl NeaMeasurementUnit {
1726 pub const fn as_str(&self) -> &'static str {
1727 match self {
1728 Self::DegC => "deg C",
1729 Self::DegreesCelsius => "Degrees Celsius",
1730 Self::Percentage => "Percentage",
1731 Self::PercentLower => "percentage",
1732 Self::Knots => "knots",
1733 Self::Degrees => "degrees",
1734 Self::Millimeters => "mm",
1735 Self::Unknown => "",
1736 }
1737 }
1738}
1739impl AsRef<str> for NeaMeasurementUnit {
1740 fn as_ref(&self) -> &str {
1741 self.as_str()
1742 }
1743}
1744impl fmt::Display for NeaMeasurementUnit {
1745 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1746 f.write_str(self.as_str())
1747 }
1748}
1749#[derive(Debug, Clone, PartialEq)]
1751#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1752pub struct NeaLightningGeoPoint {
1753 #[cfg_attr(feature = "serde", serde(with = "satay_runtime::serde_string::as_f64"))]
1755 pub latitude: f64,
1756 #[cfg_attr(feature = "serde", serde(with = "satay_runtime::serde_string::as_f64"))]
1758 pub longitude: f64,
1759}
1760#[derive(Debug, Clone, PartialEq)]
1762#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1763pub struct NeaWbgtStation {
1764 pub id: NeaStationId,
1766 pub name: String,
1768 #[cfg_attr(feature = "serde", serde(rename = "townCenter"))]
1770 pub town_center: String,
1771}
1772pub type NeaWbgt = f64;
1774#[derive(Debug, Clone, PartialEq, Eq, Default)]
1776#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1777pub enum NeaHeatStressLevel {
1778 Low,
1779 Moderate,
1780 High,
1781 #[default]
1782 #[cfg_attr(feature = "serde", serde(other))]
1783 Unknown,
1784}
1785impl NeaHeatStressLevel {
1786 pub const fn as_str(&self) -> &'static str {
1787 match self {
1788 Self::Low => "Low",
1789 Self::Moderate => "Moderate",
1790 Self::High => "High",
1791 Self::Unknown => "",
1792 }
1793 }
1794}
1795impl AsRef<str> for NeaHeatStressLevel {
1796 fn as_ref(&self) -> &str {
1797 self.as_str()
1798 }
1799}
1800impl fmt::Display for NeaHeatStressLevel {
1801 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1802 f.write_str(self.as_str())
1803 }
1804}
1805#[derive(Debug, Clone, PartialEq, Eq, Default)]
1807#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1808pub enum NeaRegionMetadataName {
1809 #[cfg_attr(feature = "serde", serde(rename = "west"))]
1810 West,
1811 #[cfg_attr(feature = "serde", serde(rename = "east"))]
1812 East,
1813 #[cfg_attr(feature = "serde", serde(rename = "north"))]
1814 North,
1815 #[cfg_attr(feature = "serde", serde(rename = "south"))]
1816 South,
1817 #[cfg_attr(feature = "serde", serde(rename = "central"))]
1818 Central,
1819 #[default]
1820 #[cfg_attr(feature = "serde", serde(other))]
1821 Unknown,
1822}
1823impl NeaRegionMetadataName {
1824 pub const fn as_str(&self) -> &'static str {
1825 match self {
1826 Self::West => "west",
1827 Self::East => "east",
1828 Self::North => "north",
1829 Self::South => "south",
1830 Self::Central => "central",
1831 Self::Unknown => "",
1832 }
1833 }
1834}
1835impl AsRef<str> for NeaRegionMetadataName {
1836 fn as_ref(&self) -> &str {
1837 self.as_str()
1838 }
1839}
1840impl fmt::Display for NeaRegionMetadataName {
1841 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1842 f.write_str(self.as_str())
1843 }
1844}