Skip to main content

weatherkit/
statistics.rs

1//! WeatherKit statistics and summary types.
2
3use 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/// Selects a WeatherKit daily statistics family.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum DailyWeatherStatisticsQuery {
16    /// Selects WeatherKit daily temperature statistics.
17    Temperature,
18    /// Selects WeatherKit daily precipitation statistics.
19    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/// Selects a WeatherKit daily summary family.
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum DailyWeatherSummaryQuery {
34    /// Selects the WeatherKit daily temperature summary.
35    Temperature,
36    /// Selects the WeatherKit daily precipitation summary.
37    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/// Selects a WeatherKit hourly statistics family.
50#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub enum HourlyWeatherStatisticsQuery {
52    /// Selects WeatherKit hourly temperature statistics.
53    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/// Selects a WeatherKit monthly statistics family.
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum MonthlyWeatherStatisticsQuery {
67    /// Selects WeatherKit monthly temperature statistics.
68    Temperature,
69    /// Selects WeatherKit monthly precipitation statistics.
70    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/// Represents WeatherKit per-day temperature statistics.
83#[derive(Debug, Clone, PartialEq, Deserialize)]
84#[serde(rename_all = "camelCase")]
85pub struct DayTemperatureStatistics {
86    /// Matches the WeatherKit day value.
87    pub day: i64,
88    /// Matches the WeatherKit average low temperature value.
89    pub average_low_temperature: f64,
90    /// Matches the WeatherKit average high temperature value.
91    pub average_high_temperature: f64,
92}
93
94/// Represents WeatherKit per-day precipitation statistics.
95#[derive(Debug, Clone, PartialEq, Deserialize)]
96#[serde(rename_all = "camelCase")]
97pub struct DayPrecipitationStatistics {
98    /// Matches the WeatherKit day value.
99    pub day: i64,
100    /// Matches the WeatherKit average precipitation probability value.
101    pub average_precipitation_probability: f64,
102    /// Matches the WeatherKit average precipitation amount value.
103    pub average_precipitation_amount: f64,
104    /// Matches the WeatherKit average snowfall amount value.
105    pub average_snowfall_amount: f64,
106}
107
108/// Represents WeatherKit per-hour temperature statistics.
109#[derive(Debug, Clone, PartialEq, Deserialize)]
110#[serde(rename_all = "camelCase")]
111pub struct HourTemperatureStatistics {
112    /// Matches the WeatherKit hour value.
113    pub hour: i64,
114    /// Matches the WeatherKit percentiles value.
115    pub percentiles: Percentiles<TemperatureUnit>,
116}
117
118/// Represents WeatherKit per-month temperature statistics.
119#[derive(Debug, Clone, PartialEq, Deserialize)]
120#[serde(rename_all = "camelCase")]
121pub struct MonthTemperatureStatistics {
122    /// Matches the WeatherKit month value.
123    pub month: i64,
124    /// Matches the WeatherKit average low temperature value.
125    pub average_low_temperature: f64,
126    /// Matches the WeatherKit average high temperature value.
127    pub average_high_temperature: f64,
128}
129
130/// Represents WeatherKit per-month precipitation statistics.
131#[derive(Debug, Clone, PartialEq, Deserialize)]
132#[serde(rename_all = "camelCase")]
133pub struct MonthPrecipitationStatistics {
134    /// Matches the WeatherKit month value.
135    pub month: i64,
136    /// Matches the WeatherKit average precipitation probability value.
137    pub average_precipitation_probability: f64,
138    /// Matches the WeatherKit average precipitation amount value.
139    pub average_precipitation_amount: f64,
140    /// Matches the WeatherKit average snowfall amount value.
141    pub average_snowfall_amount: f64,
142}
143
144/// Represents a WeatherKit daily temperature summary.
145#[derive(Debug, Clone, PartialEq, Deserialize)]
146#[serde(rename_all = "camelCase")]
147pub struct DayTemperatureSummary {
148    /// Matches the WeatherKit date value.
149    pub date: String,
150    /// Matches the WeatherKit low temperature value.
151    pub low_temperature: f64,
152    /// Matches the WeatherKit high temperature value.
153    pub high_temperature: f64,
154}
155
156/// Represents a WeatherKit daily precipitation summary.
157#[derive(Debug, Clone, PartialEq, Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub struct DayPrecipitationSummary {
160    /// Matches the WeatherKit date value.
161    pub date: String,
162    /// Matches the WeatherKit precipitation amount value.
163    pub precipitation_amount: f64,
164    /// Matches the WeatherKit snowfall amount value.
165    pub snowfall_amount: f64,
166}
167
168/// Wraps WeatherKit daily statistics results.
169#[derive(Debug, Clone, PartialEq, Deserialize)]
170#[serde(rename_all = "camelCase")]
171pub struct DailyWeatherStatistics<T> {
172    /// Matches the WeatherKit days value.
173    pub days: Vec<T>,
174    /// Matches the WeatherKit baseline start date value.
175    pub baseline_start_date: String,
176    /// Matches the WeatherKit metadata value.
177    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    /// Returns the number of WeatherKit day entries in this collection.
196    pub fn len(&self) -> usize {
197        self.days.len()
198    }
199
200    /// Returns whether this WeatherKit day collection is empty.
201    pub fn is_empty(&self) -> bool {
202        self.days.is_empty()
203    }
204
205    /// Iterates over the WeatherKit day entries in this collection.
206    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/// Wraps WeatherKit daily summary results.
221#[derive(Debug, Clone, PartialEq, Deserialize)]
222#[serde(rename_all = "camelCase")]
223pub struct DailyWeatherSummary<T> {
224    /// Matches the WeatherKit days value.
225    pub days: Vec<T>,
226    /// Matches the WeatherKit metadata value.
227    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    /// Returns the number of WeatherKit summary entries in this collection.
246    pub fn len(&self) -> usize {
247        self.days.len()
248    }
249
250    /// Returns whether this WeatherKit summary collection is empty.
251    pub fn is_empty(&self) -> bool {
252        self.days.is_empty()
253    }
254
255    /// Iterates over the WeatherKit summary entries in this collection.
256    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/// Wraps WeatherKit hourly statistics results.
271#[derive(Debug, Clone, PartialEq, Deserialize)]
272#[serde(rename_all = "camelCase")]
273pub struct HourlyWeatherStatistics<T> {
274    /// Matches the WeatherKit hours value.
275    pub hours: Vec<T>,
276    /// Matches the WeatherKit baseline start date value.
277    pub baseline_start_date: String,
278    /// Matches the WeatherKit metadata value.
279    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    /// Returns the number of WeatherKit hour entries in this collection.
298    pub fn len(&self) -> usize {
299        self.hours.len()
300    }
301
302    /// Returns whether this WeatherKit hour collection is empty.
303    pub fn is_empty(&self) -> bool {
304        self.hours.is_empty()
305    }
306
307    /// Iterates over the WeatherKit hour entries in this collection.
308    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/// Wraps WeatherKit monthly statistics results.
323#[derive(Debug, Clone, PartialEq, Deserialize)]
324#[serde(rename_all = "camelCase")]
325pub struct MonthlyWeatherStatistics<T> {
326    /// Matches the WeatherKit months value.
327    pub months: Vec<T>,
328    /// Matches the WeatherKit baseline start date value.
329    pub baseline_start_date: String,
330    /// Matches the WeatherKit metadata value.
331    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    /// Returns the number of WeatherKit month entries in this collection.
350    pub fn len(&self) -> usize {
351        self.months.len()
352    }
353
354    /// Returns whether this WeatherKit month collection is empty.
355    pub fn is_empty(&self) -> bool {
356        self.months.is_empty()
357    }
358
359    /// Iterates over the WeatherKit month entries in this collection.
360    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/// Wraps a typed WeatherKit daily statistics result.
375#[derive(Debug, Clone, PartialEq)]
376pub enum DailyWeatherStatisticsResult {
377    /// Carries WeatherKit daily temperature statistics.
378    Temperature(DailyWeatherStatistics<DayTemperatureStatistics>),
379    /// Carries WeatherKit daily precipitation statistics.
380    Precipitation(DailyWeatherStatistics<DayPrecipitationStatistics>),
381}
382
383/// Wraps a typed WeatherKit daily summary result.
384#[derive(Debug, Clone, PartialEq)]
385pub enum DailyWeatherSummaryResult {
386    /// Carries the WeatherKit daily temperature summary.
387    Temperature(DailyWeatherSummary<DayTemperatureSummary>),
388    /// Carries the WeatherKit daily precipitation summary.
389    Precipitation(DailyWeatherSummary<DayPrecipitationSummary>),
390}
391
392/// Wraps a typed WeatherKit monthly statistics result.
393#[derive(Debug, Clone, PartialEq)]
394pub enum MonthlyWeatherStatisticsResult {
395    /// Carries WeatherKit monthly temperature statistics.
396    Temperature(MonthlyWeatherStatistics<MonthTemperatureStatistics>),
397    /// Carries WeatherKit monthly precipitation statistics.
398    Precipitation(MonthlyWeatherStatistics<MonthPrecipitationStatistics>),
399}