1use serde::{Deserialize, Deserializer};
4
5use crate::error::WeatherKitError;
6use crate::ffi;
7use crate::private::parse_json_from_static;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum WeatherCondition {
13 Blizzard,
15 BlowingDust,
17 BlowingSnow,
19 Breezy,
21 Clear,
23 Cloudy,
25 Drizzle,
27 Flurries,
29 Foggy,
31 FreezingDrizzle,
33 FreezingRain,
35 Frigid,
37 Hail,
39 Haze,
41 HeavyRain,
43 HeavySnow,
45 Hot,
47 Hurricane,
49 IsolatedThunderstorms,
51 MostlyClear,
53 MostlyCloudy,
55 PartlyCloudy,
57 Rain,
59 ScatteredThunderstorms,
61 Sleet,
63 Smoky,
65 Snow,
67 StrongStorms,
69 SunFlurries,
71 SunShowers,
73 Thunderstorms,
75 TropicalStorm,
77 Windy,
79 WintryMix,
81 Unknown(String),
83}
84
85impl WeatherCondition {
86 pub(crate) fn from_raw(value: String) -> Self {
87 match value.as_str() {
88 "blizzard" => Self::Blizzard,
89 "blowingDust" => Self::BlowingDust,
90 "blowingSnow" => Self::BlowingSnow,
91 "breezy" => Self::Breezy,
92 "clear" => Self::Clear,
93 "cloudy" => Self::Cloudy,
94 "drizzle" => Self::Drizzle,
95 "flurries" => Self::Flurries,
96 "foggy" => Self::Foggy,
97 "freezingDrizzle" => Self::FreezingDrizzle,
98 "freezingRain" => Self::FreezingRain,
99 "frigid" => Self::Frigid,
100 "hail" => Self::Hail,
101 "haze" => Self::Haze,
102 "heavyRain" => Self::HeavyRain,
103 "heavySnow" => Self::HeavySnow,
104 "hot" => Self::Hot,
105 "hurricane" => Self::Hurricane,
106 "isolatedThunderstorms" => Self::IsolatedThunderstorms,
107 "mostlyClear" => Self::MostlyClear,
108 "mostlyCloudy" => Self::MostlyCloudy,
109 "partlyCloudy" => Self::PartlyCloudy,
110 "rain" => Self::Rain,
111 "scatteredThunderstorms" => Self::ScatteredThunderstorms,
112 "sleet" => Self::Sleet,
113 "smoky" => Self::Smoky,
114 "snow" => Self::Snow,
115 "strongStorms" => Self::StrongStorms,
116 "sunFlurries" => Self::SunFlurries,
117 "sunShowers" => Self::SunShowers,
118 "thunderstorms" => Self::Thunderstorms,
119 "tropicalStorm" => Self::TropicalStorm,
120 "windy" => Self::Windy,
121 "wintryMix" => Self::WintryMix,
122 other => Self::Unknown(other.to_owned()),
123 }
124 }
125
126 pub fn raw_value(&self) -> &str {
128 match self {
129 Self::Blizzard => "blizzard",
130 Self::BlowingDust => "blowingDust",
131 Self::BlowingSnow => "blowingSnow",
132 Self::Breezy => "breezy",
133 Self::Clear => "clear",
134 Self::Cloudy => "cloudy",
135 Self::Drizzle => "drizzle",
136 Self::Flurries => "flurries",
137 Self::Foggy => "foggy",
138 Self::FreezingDrizzle => "freezingDrizzle",
139 Self::FreezingRain => "freezingRain",
140 Self::Frigid => "frigid",
141 Self::Hail => "hail",
142 Self::Haze => "haze",
143 Self::HeavyRain => "heavyRain",
144 Self::HeavySnow => "heavySnow",
145 Self::Hot => "hot",
146 Self::Hurricane => "hurricane",
147 Self::IsolatedThunderstorms => "isolatedThunderstorms",
148 Self::MostlyClear => "mostlyClear",
149 Self::MostlyCloudy => "mostlyCloudy",
150 Self::PartlyCloudy => "partlyCloudy",
151 Self::Rain => "rain",
152 Self::ScatteredThunderstorms => "scatteredThunderstorms",
153 Self::Sleet => "sleet",
154 Self::Smoky => "smoky",
155 Self::Snow => "snow",
156 Self::StrongStorms => "strongStorms",
157 Self::SunFlurries => "sunFlurries",
158 Self::SunShowers => "sunShowers",
159 Self::Thunderstorms => "thunderstorms",
160 Self::TropicalStorm => "tropicalStorm",
161 Self::Windy => "windy",
162 Self::WintryMix => "wintryMix",
163 Self::Unknown(value) => value.as_str(),
164 }
165 }
166
167 pub fn descriptors() -> Result<Vec<WeatherConditionDescriptor>, WeatherKitError> {
169 parse_json_from_static(
170 ffi::weather_condition::wk_weather_condition_copy_descriptors_json,
171 "weather condition descriptors",
172 )
173 }
174}
175
176#[derive(Debug, Clone, PartialEq, Eq)]
178#[non_exhaustive]
179pub enum Precipitation {
180 None,
182 Hail,
184 Mixed,
186 Rain,
188 Sleet,
190 Snow,
192 Unknown(String),
194}
195
196impl Precipitation {
197 pub(crate) fn from_raw(value: String) -> Self {
198 match value.as_str() {
199 "none" => Self::None,
200 "hail" => Self::Hail,
201 "mixed" => Self::Mixed,
202 "rain" => Self::Rain,
203 "sleet" => Self::Sleet,
204 "snow" => Self::Snow,
205 other => Self::Unknown(other.to_owned()),
206 }
207 }
208
209 pub fn raw_value(&self) -> &str {
211 match self {
212 Self::None => "none",
213 Self::Hail => "hail",
214 Self::Mixed => "mixed",
215 Self::Rain => "rain",
216 Self::Sleet => "sleet",
217 Self::Snow => "snow",
218 Self::Unknown(value) => value.as_str(),
219 }
220 }
221
222 pub fn descriptors() -> Result<Vec<PrecipitationDescriptor>, WeatherKitError> {
224 parse_json_from_static(
225 ffi::weather_condition::wk_precipitation_copy_descriptors_json,
226 "precipitation descriptors",
227 )
228 }
229}
230
231#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
233#[serde(rename_all = "camelCase")]
234pub struct PrecipitationDescriptor {
235 pub raw_value: String,
237 pub description: String,
239 pub accessibility_description: String,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
245#[serde(rename_all = "camelCase")]
246pub struct WeatherConditionDescriptor {
247 pub raw_value: String,
249 pub description: String,
251 pub accessibility_description: String,
253}
254
255pub(crate) fn deserialize_weather_condition<'de, D>(
256 deserializer: D,
257) -> Result<WeatherCondition, D::Error>
258where
259 D: Deserializer<'de>,
260{
261 let raw = String::deserialize(deserializer)?;
262 Ok(WeatherCondition::from_raw(raw))
263}
264
265pub(crate) fn deserialize_precipitation<'de, D>(deserializer: D) -> Result<Precipitation, D::Error>
266where
267 D: Deserializer<'de>,
268{
269 let raw = String::deserialize(deserializer)?;
270 Ok(Precipitation::from_raw(raw))
271}