1use core::ffi::c_void;
4
5use serde::Deserialize;
6
7use crate::changes::{Percentiles, TemperatureUnit};
8use crate::error::WeatherKitError;
9use crate::ffi;
10use crate::private::parse_json_from_handle;
11use crate::service::WeatherMetadata;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum DailyWeatherStatisticsQuery {
16 Temperature,
18 Precipitation,
20}
21
22impl DailyWeatherStatisticsQuery {
23 pub(crate) const fn query_kind(self) -> i32 {
24 match self {
25 Self::Temperature => 0,
26 Self::Precipitation => 1,
27 }
28 }
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum DailyWeatherSummaryQuery {
34 Temperature,
36 Precipitation,
38}
39
40impl DailyWeatherSummaryQuery {
41 pub(crate) const fn query_kind(self) -> i32 {
42 match self {
43 Self::Temperature => 0,
44 Self::Precipitation => 1,
45 }
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub enum HourlyWeatherStatisticsQuery {
52 Temperature,
54}
55
56impl HourlyWeatherStatisticsQuery {
57 pub(crate) const fn query_kind(self) -> i32 {
58 match self {
59 Self::Temperature => 0,
60 }
61 }
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum MonthlyWeatherStatisticsQuery {
67 Temperature,
69 Precipitation,
71}
72
73impl MonthlyWeatherStatisticsQuery {
74 pub(crate) const fn query_kind(self) -> i32 {
75 match self {
76 Self::Temperature => 0,
77 Self::Precipitation => 1,
78 }
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Deserialize)]
84#[serde(rename_all = "camelCase")]
85pub struct DayTemperatureStatistics {
86 pub day: i64,
88 pub average_low_temperature: f64,
90 pub average_high_temperature: f64,
92}
93
94#[derive(Debug, Clone, PartialEq, Deserialize)]
96#[serde(rename_all = "camelCase")]
97pub struct DayPrecipitationStatistics {
98 pub day: i64,
100 pub average_precipitation_probability: f64,
102 pub average_precipitation_amount: f64,
104 pub average_snowfall_amount: f64,
106}
107
108#[derive(Debug, Clone, PartialEq, Deserialize)]
110#[serde(rename_all = "camelCase")]
111pub struct HourTemperatureStatistics {
112 pub hour: i64,
114 pub percentiles: Percentiles<TemperatureUnit>,
116}
117
118#[derive(Debug, Clone, PartialEq, Deserialize)]
120#[serde(rename_all = "camelCase")]
121pub struct MonthTemperatureStatistics {
122 pub month: i64,
124 pub average_low_temperature: f64,
126 pub average_high_temperature: f64,
128}
129
130#[derive(Debug, Clone, PartialEq, Deserialize)]
132#[serde(rename_all = "camelCase")]
133pub struct MonthPrecipitationStatistics {
134 pub month: i64,
136 pub average_precipitation_probability: f64,
138 pub average_precipitation_amount: f64,
140 pub average_snowfall_amount: f64,
142}
143
144#[derive(Debug, Clone, PartialEq, Deserialize)]
146#[serde(rename_all = "camelCase")]
147pub struct DayTemperatureSummary {
148 pub date: String,
150 pub low_temperature: f64,
152 pub high_temperature: f64,
154}
155
156#[derive(Debug, Clone, PartialEq, Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub struct DayPrecipitationSummary {
160 pub date: String,
162 pub precipitation_amount: f64,
164 pub snowfall_amount: f64,
166}
167
168#[derive(Debug, Clone, PartialEq, Deserialize)]
170#[serde(rename_all = "camelCase")]
171pub struct DailyWeatherStatistics<T> {
172 pub days: Vec<T>,
174 pub baseline_start_date: String,
176 pub metadata: WeatherMetadata,
178}
179
180impl<T> DailyWeatherStatistics<T>
181where
182 T: for<'de> Deserialize<'de>,
183{
184 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
185 parse_json_from_handle(
186 ptr,
187 ffi::json_handle::wk_json_handle_release,
188 ffi::json_handle::wk_json_handle_copy_json,
189 "daily weather statistics",
190 )
191 }
192}
193
194impl<T> DailyWeatherStatistics<T> {
195 pub fn len(&self) -> usize {
197 self.days.len()
198 }
199
200 pub fn is_empty(&self) -> bool {
202 self.days.is_empty()
203 }
204
205 pub fn iter(&self) -> std::slice::Iter<'_, T> {
207 self.days.iter()
208 }
209}
210
211impl<'a, T> IntoIterator for &'a DailyWeatherStatistics<T> {
212 type Item = &'a T;
213 type IntoIter = std::slice::Iter<'a, T>;
214
215 fn into_iter(self) -> Self::IntoIter {
216 self.iter()
217 }
218}
219
220#[derive(Debug, Clone, PartialEq, Deserialize)]
222#[serde(rename_all = "camelCase")]
223pub struct DailyWeatherSummary<T> {
224 pub days: Vec<T>,
226 pub metadata: WeatherMetadata,
228}
229
230impl<T> DailyWeatherSummary<T>
231where
232 T: for<'de> Deserialize<'de>,
233{
234 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
235 parse_json_from_handle(
236 ptr,
237 ffi::json_handle::wk_json_handle_release,
238 ffi::json_handle::wk_json_handle_copy_json,
239 "daily weather summary",
240 )
241 }
242}
243
244impl<T> DailyWeatherSummary<T> {
245 pub fn len(&self) -> usize {
247 self.days.len()
248 }
249
250 pub fn is_empty(&self) -> bool {
252 self.days.is_empty()
253 }
254
255 pub fn iter(&self) -> std::slice::Iter<'_, T> {
257 self.days.iter()
258 }
259}
260
261impl<'a, T> IntoIterator for &'a DailyWeatherSummary<T> {
262 type Item = &'a T;
263 type IntoIter = std::slice::Iter<'a, T>;
264
265 fn into_iter(self) -> Self::IntoIter {
266 self.iter()
267 }
268}
269
270#[derive(Debug, Clone, PartialEq, Deserialize)]
272#[serde(rename_all = "camelCase")]
273pub struct HourlyWeatherStatistics<T> {
274 pub hours: Vec<T>,
276 pub baseline_start_date: String,
278 pub metadata: WeatherMetadata,
280}
281
282impl<T> HourlyWeatherStatistics<T>
283where
284 T: for<'de> Deserialize<'de>,
285{
286 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
287 parse_json_from_handle(
288 ptr,
289 ffi::json_handle::wk_json_handle_release,
290 ffi::json_handle::wk_json_handle_copy_json,
291 "hourly weather statistics",
292 )
293 }
294}
295
296impl<T> HourlyWeatherStatistics<T> {
297 pub fn len(&self) -> usize {
299 self.hours.len()
300 }
301
302 pub fn is_empty(&self) -> bool {
304 self.hours.is_empty()
305 }
306
307 pub fn iter(&self) -> std::slice::Iter<'_, T> {
309 self.hours.iter()
310 }
311}
312
313impl<'a, T> IntoIterator for &'a HourlyWeatherStatistics<T> {
314 type Item = &'a T;
315 type IntoIter = std::slice::Iter<'a, T>;
316
317 fn into_iter(self) -> Self::IntoIter {
318 self.iter()
319 }
320}
321
322#[derive(Debug, Clone, PartialEq, Deserialize)]
324#[serde(rename_all = "camelCase")]
325pub struct MonthlyWeatherStatistics<T> {
326 pub months: Vec<T>,
328 pub baseline_start_date: String,
330 pub metadata: WeatherMetadata,
332}
333
334impl<T> MonthlyWeatherStatistics<T>
335where
336 T: for<'de> Deserialize<'de>,
337{
338 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
339 parse_json_from_handle(
340 ptr,
341 ffi::json_handle::wk_json_handle_release,
342 ffi::json_handle::wk_json_handle_copy_json,
343 "monthly weather statistics",
344 )
345 }
346}
347
348impl<T> MonthlyWeatherStatistics<T> {
349 pub fn len(&self) -> usize {
351 self.months.len()
352 }
353
354 pub fn is_empty(&self) -> bool {
356 self.months.is_empty()
357 }
358
359 pub fn iter(&self) -> std::slice::Iter<'_, T> {
361 self.months.iter()
362 }
363}
364
365impl<'a, T> IntoIterator for &'a MonthlyWeatherStatistics<T> {
366 type Item = &'a T;
367 type IntoIter = std::slice::Iter<'a, T>;
368
369 fn into_iter(self) -> Self::IntoIter {
370 self.iter()
371 }
372}
373
374#[derive(Debug, Clone, PartialEq)]
376pub enum DailyWeatherStatisticsResult {
377 Temperature(DailyWeatherStatistics<DayTemperatureStatistics>),
379 Precipitation(DailyWeatherStatistics<DayPrecipitationStatistics>),
381}
382
383#[derive(Debug, Clone, PartialEq)]
385pub enum DailyWeatherSummaryResult {
386 Temperature(DailyWeatherSummary<DayTemperatureSummary>),
388 Precipitation(DailyWeatherSummary<DayPrecipitationSummary>),
390}
391
392#[derive(Debug, Clone, PartialEq)]
394pub enum MonthlyWeatherStatisticsResult {
395 Temperature(MonthlyWeatherStatistics<MonthTemperatureStatistics>),
397 Precipitation(MonthlyWeatherStatistics<MonthPrecipitationStatistics>),
399}