1use core::ffi::c_void;
2
3use serde::Deserialize;
4
5use crate::changes::{Percentiles, TemperatureUnit};
6use crate::error::WeatherKitError;
7use crate::ffi;
8use crate::private::parse_json_from_handle;
9use crate::service::WeatherMetadata;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum DailyWeatherStatisticsQuery {
13 Temperature,
14 Precipitation,
15}
16
17impl DailyWeatherStatisticsQuery {
18 pub(crate) const fn query_kind(self) -> i32 {
19 match self {
20 Self::Temperature => 0,
21 Self::Precipitation => 1,
22 }
23 }
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum DailyWeatherSummaryQuery {
28 Temperature,
29 Precipitation,
30}
31
32impl DailyWeatherSummaryQuery {
33 pub(crate) const fn query_kind(self) -> i32 {
34 match self {
35 Self::Temperature => 0,
36 Self::Precipitation => 1,
37 }
38 }
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum HourlyWeatherStatisticsQuery {
43 Temperature,
44}
45
46impl HourlyWeatherStatisticsQuery {
47 pub(crate) const fn query_kind(self) -> i32 {
48 match self {
49 Self::Temperature => 0,
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum MonthlyWeatherStatisticsQuery {
56 Temperature,
57 Precipitation,
58}
59
60impl MonthlyWeatherStatisticsQuery {
61 pub(crate) const fn query_kind(self) -> i32 {
62 match self {
63 Self::Temperature => 0,
64 Self::Precipitation => 1,
65 }
66 }
67}
68
69#[derive(Debug, Clone, PartialEq, Deserialize)]
70#[serde(rename_all = "camelCase")]
71pub struct DayTemperatureStatistics {
72 pub day: i64,
73 pub average_low_temperature: f64,
74 pub average_high_temperature: f64,
75}
76
77#[derive(Debug, Clone, PartialEq, Deserialize)]
78#[serde(rename_all = "camelCase")]
79pub struct DayPrecipitationStatistics {
80 pub day: i64,
81 pub average_precipitation_probability: f64,
82 pub average_precipitation_amount: f64,
83 pub average_snowfall_amount: f64,
84}
85
86#[derive(Debug, Clone, PartialEq, Deserialize)]
87#[serde(rename_all = "camelCase")]
88pub struct HourTemperatureStatistics {
89 pub hour: i64,
90 pub percentiles: Percentiles<TemperatureUnit>,
91}
92
93#[derive(Debug, Clone, PartialEq, Deserialize)]
94#[serde(rename_all = "camelCase")]
95pub struct MonthTemperatureStatistics {
96 pub month: i64,
97 pub average_low_temperature: f64,
98 pub average_high_temperature: f64,
99}
100
101#[derive(Debug, Clone, PartialEq, Deserialize)]
102#[serde(rename_all = "camelCase")]
103pub struct MonthPrecipitationStatistics {
104 pub month: i64,
105 pub average_precipitation_probability: f64,
106 pub average_precipitation_amount: f64,
107 pub average_snowfall_amount: f64,
108}
109
110#[derive(Debug, Clone, PartialEq, Deserialize)]
111#[serde(rename_all = "camelCase")]
112pub struct DayTemperatureSummary {
113 pub date: String,
114 pub low_temperature: f64,
115 pub high_temperature: f64,
116}
117
118#[derive(Debug, Clone, PartialEq, Deserialize)]
119#[serde(rename_all = "camelCase")]
120pub struct DayPrecipitationSummary {
121 pub date: String,
122 pub precipitation_amount: f64,
123 pub snowfall_amount: f64,
124}
125
126#[derive(Debug, Clone, PartialEq, Deserialize)]
127#[serde(rename_all = "camelCase")]
128pub struct DailyWeatherStatistics<T> {
129 pub days: Vec<T>,
130 pub baseline_start_date: String,
131 pub metadata: WeatherMetadata,
132}
133
134impl<T> DailyWeatherStatistics<T>
135where
136 T: for<'de> Deserialize<'de>,
137{
138 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
139 parse_json_from_handle(
140 ptr,
141 ffi::json_handle::wk_json_handle_release,
142 ffi::json_handle::wk_json_handle_copy_json,
143 "daily weather statistics",
144 )
145 }
146}
147
148impl<T> DailyWeatherStatistics<T> {
149 pub fn len(&self) -> usize {
150 self.days.len()
151 }
152
153 pub fn is_empty(&self) -> bool {
154 self.days.is_empty()
155 }
156
157 pub fn iter(&self) -> std::slice::Iter<'_, T> {
158 self.days.iter()
159 }
160}
161
162impl<'a, T> IntoIterator for &'a DailyWeatherStatistics<T> {
163 type Item = &'a T;
164 type IntoIter = std::slice::Iter<'a, T>;
165
166 fn into_iter(self) -> Self::IntoIter {
167 self.iter()
168 }
169}
170
171#[derive(Debug, Clone, PartialEq, Deserialize)]
172#[serde(rename_all = "camelCase")]
173pub struct DailyWeatherSummary<T> {
174 pub days: Vec<T>,
175 pub metadata: WeatherMetadata,
176}
177
178impl<T> DailyWeatherSummary<T>
179where
180 T: for<'de> Deserialize<'de>,
181{
182 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
183 parse_json_from_handle(
184 ptr,
185 ffi::json_handle::wk_json_handle_release,
186 ffi::json_handle::wk_json_handle_copy_json,
187 "daily weather summary",
188 )
189 }
190}
191
192impl<T> DailyWeatherSummary<T> {
193 pub fn len(&self) -> usize {
194 self.days.len()
195 }
196
197 pub fn is_empty(&self) -> bool {
198 self.days.is_empty()
199 }
200
201 pub fn iter(&self) -> std::slice::Iter<'_, T> {
202 self.days.iter()
203 }
204}
205
206impl<'a, T> IntoIterator for &'a DailyWeatherSummary<T> {
207 type Item = &'a T;
208 type IntoIter = std::slice::Iter<'a, T>;
209
210 fn into_iter(self) -> Self::IntoIter {
211 self.iter()
212 }
213}
214
215#[derive(Debug, Clone, PartialEq, Deserialize)]
216#[serde(rename_all = "camelCase")]
217pub struct HourlyWeatherStatistics<T> {
218 pub hours: Vec<T>,
219 pub baseline_start_date: String,
220 pub metadata: WeatherMetadata,
221}
222
223impl<T> HourlyWeatherStatistics<T>
224where
225 T: for<'de> Deserialize<'de>,
226{
227 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
228 parse_json_from_handle(
229 ptr,
230 ffi::json_handle::wk_json_handle_release,
231 ffi::json_handle::wk_json_handle_copy_json,
232 "hourly weather statistics",
233 )
234 }
235}
236
237impl<T> HourlyWeatherStatistics<T> {
238 pub fn len(&self) -> usize {
239 self.hours.len()
240 }
241
242 pub fn is_empty(&self) -> bool {
243 self.hours.is_empty()
244 }
245
246 pub fn iter(&self) -> std::slice::Iter<'_, T> {
247 self.hours.iter()
248 }
249}
250
251impl<'a, T> IntoIterator for &'a HourlyWeatherStatistics<T> {
252 type Item = &'a T;
253 type IntoIter = std::slice::Iter<'a, T>;
254
255 fn into_iter(self) -> Self::IntoIter {
256 self.iter()
257 }
258}
259
260#[derive(Debug, Clone, PartialEq, Deserialize)]
261#[serde(rename_all = "camelCase")]
262pub struct MonthlyWeatherStatistics<T> {
263 pub months: Vec<T>,
264 pub baseline_start_date: String,
265 pub metadata: WeatherMetadata,
266}
267
268impl<T> MonthlyWeatherStatistics<T>
269where
270 T: for<'de> Deserialize<'de>,
271{
272 pub(crate) fn from_owned_ptr(ptr: *mut c_void) -> Result<Self, WeatherKitError> {
273 parse_json_from_handle(
274 ptr,
275 ffi::json_handle::wk_json_handle_release,
276 ffi::json_handle::wk_json_handle_copy_json,
277 "monthly weather statistics",
278 )
279 }
280}
281
282impl<T> MonthlyWeatherStatistics<T> {
283 pub fn len(&self) -> usize {
284 self.months.len()
285 }
286
287 pub fn is_empty(&self) -> bool {
288 self.months.is_empty()
289 }
290
291 pub fn iter(&self) -> std::slice::Iter<'_, T> {
292 self.months.iter()
293 }
294}
295
296impl<'a, T> IntoIterator for &'a MonthlyWeatherStatistics<T> {
297 type Item = &'a T;
298 type IntoIter = std::slice::Iter<'a, T>;
299
300 fn into_iter(self) -> Self::IntoIter {
301 self.iter()
302 }
303}
304
305#[derive(Debug, Clone, PartialEq)]
306pub enum DailyWeatherStatisticsResult {
307 Temperature(DailyWeatherStatistics<DayTemperatureStatistics>),
308 Precipitation(DailyWeatherStatistics<DayPrecipitationStatistics>),
309}
310
311#[derive(Debug, Clone, PartialEq)]
312pub enum DailyWeatherSummaryResult {
313 Temperature(DailyWeatherSummary<DayTemperatureSummary>),
314 Precipitation(DailyWeatherSummary<DayPrecipitationSummary>),
315}
316
317#[derive(Debug, Clone, PartialEq)]
318pub enum MonthlyWeatherStatisticsResult {
319 Temperature(MonthlyWeatherStatistics<MonthTemperatureStatistics>),
320 Precipitation(MonthlyWeatherStatistics<MonthPrecipitationStatistics>),
321}