1use std::borrow::Cow;
2
3use crate::query::AsApiStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
7#[non_exhaustive]
8pub enum Aggregation {
9 Minimum,
11 Maximum,
13 Mean,
15 Median,
17 Sum,
19 P10,
21 P25,
23 P75,
25 P90,
27 Dominant,
29}
30
31impl Aggregation {
32 pub fn suffix(self) -> &'static str {
34 match self {
35 Self::Minimum => "_min",
36 Self::Maximum => "_max",
37 Self::Mean => "_mean",
38 Self::Median => "_median",
39 Self::Sum => "_sum",
40 Self::P10 => "_p10",
41 Self::P25 => "_p25",
42 Self::P75 => "_p75",
43 Self::P90 => "_p90",
44 Self::Dominant => "_dominant",
45 }
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
51#[repr(i16)]
52#[non_exhaustive]
53pub enum PressureLevel {
54 Hpa1000 = 1000,
56 Hpa975 = 975,
58 Hpa950 = 950,
60 Hpa925 = 925,
62 Hpa900 = 900,
64 Hpa850 = 850,
66 Hpa800 = 800,
68 Hpa700 = 700,
70 Hpa600 = 600,
72 Hpa500 = 500,
74 Hpa400 = 400,
76 Hpa300 = 300,
78 Hpa250 = 250,
80 Hpa200 = 200,
82 Hpa150 = 150,
84 Hpa100 = 100,
86 Hpa70 = 70,
88 Hpa50 = 50,
90 Hpa30 = 30,
92}
93
94impl PressureLevel {
95 pub(crate) fn hpa(self) -> i16 {
96 self as i16
97 }
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
102#[repr(i16)]
103#[non_exhaustive]
104pub enum TowerLevel {
105 M10 = 10,
107 M80 = 80,
109 M120 = 120,
111 M180 = 180,
113}
114
115impl TowerLevel {
116 pub(crate) fn meters(self) -> i16 {
117 self as i16
118 }
119}
120
121#[derive(Debug, Clone, PartialEq, Eq, Hash)]
123#[non_exhaustive]
124pub enum WeatherModel {
125 BestMatch,
127 GfsSeamless,
129 EcmwfIfs025,
131 IconSeamless,
133 MeteofranceSeamless,
135 Other(Cow<'static, str>),
141}
142
143#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145#[non_exhaustive]
146pub enum ArchiveModel {
147 BestMatch,
149 Era5Seamless,
151 Era5,
153 Era5Land,
155 Era5Ensemble,
157 EcmwfIfs,
159 EcmwfIfsAnalysisLongWindow,
161 Cerra,
163 Other(Cow<'static, str>),
169}
170
171#[derive(Debug, Clone, PartialEq, Eq, Hash)]
173#[non_exhaustive]
174pub enum EnsembleModel {
175 IconSeamlessEps,
177 IconGlobalEps,
179 IconEuEps,
181 IconD2Eps,
183 NcepGefsSeamless,
185 NcepGefs025,
187 NcepGefs05,
189 NcepAigefs025,
191 EcmwfIfs025Ensemble,
193 EcmwfAifs025Ensemble,
195 GemGlobalEnsemble,
197 BomAccessGlobalEnsemble,
199 UkmoGlobalEnsemble20km,
201 UkmoUkEnsemble2km,
203 MeteoswissIconCh1Ensemble,
205 MeteoswissIconCh2Ensemble,
207 Other(Cow<'static, str>),
211}
212
213impl EnsembleModel {
214 pub fn other(token: impl Into<Cow<'static, str>>) -> Self {
218 Self::Other(token.into())
219 }
220}
221
222impl AsApiStr for EnsembleModel {
223 fn as_api_str(&self) -> Cow<'static, str> {
224 match self {
225 Self::IconSeamlessEps => Cow::Borrowed("icon_seamless_eps"),
226 Self::IconGlobalEps => Cow::Borrowed("icon_global_eps"),
227 Self::IconEuEps => Cow::Borrowed("icon_eu_eps"),
228 Self::IconD2Eps => Cow::Borrowed("icon_d2_eps"),
229 Self::NcepGefsSeamless => Cow::Borrowed("ncep_gefs_seamless"),
230 Self::NcepGefs025 => Cow::Borrowed("ncep_gefs025"),
231 Self::NcepGefs05 => Cow::Borrowed("ncep_gefs05"),
232 Self::NcepAigefs025 => Cow::Borrowed("ncep_aigefs025"),
233 Self::EcmwfIfs025Ensemble => Cow::Borrowed("ecmwf_ifs025_ensemble"),
234 Self::EcmwfAifs025Ensemble => Cow::Borrowed("ecmwf_aifs025_ensemble"),
235 Self::GemGlobalEnsemble => Cow::Borrowed("gem_global_ensemble"),
236 Self::BomAccessGlobalEnsemble => Cow::Borrowed("bom_access_global_ensemble"),
237 Self::UkmoGlobalEnsemble20km => Cow::Borrowed("ukmo_global_ensemble_20km"),
238 Self::UkmoUkEnsemble2km => Cow::Borrowed("ukmo_uk_ensemble_2km"),
239 Self::MeteoswissIconCh1Ensemble => Cow::Borrowed("meteoswiss_icon_ch1_ensemble"),
240 Self::MeteoswissIconCh2Ensemble => Cow::Borrowed("meteoswiss_icon_ch2_ensemble"),
241 Self::Other(token) => token.clone(),
242 }
243 }
244}
245
246impl ArchiveModel {
247 pub fn other(token: impl Into<Cow<'static, str>>) -> Self {
251 Self::Other(token.into())
252 }
253}
254
255impl AsApiStr for ArchiveModel {
256 fn as_api_str(&self) -> Cow<'static, str> {
257 match self {
258 Self::BestMatch => Cow::Borrowed("best_match"),
259 Self::Era5Seamless => Cow::Borrowed("era5_seamless"),
260 Self::Era5 => Cow::Borrowed("era5"),
261 Self::Era5Land => Cow::Borrowed("era5_land"),
262 Self::Era5Ensemble => Cow::Borrowed("era5_ensemble"),
263 Self::EcmwfIfs => Cow::Borrowed("ecmwf_ifs"),
264 Self::EcmwfIfsAnalysisLongWindow => Cow::Borrowed("ecmwf_ifs_analysis_long_window"),
265 Self::Cerra => Cow::Borrowed("cerra"),
266 Self::Other(token) => token.clone(),
267 }
268 }
269}
270
271impl WeatherModel {
272 pub fn other(token: impl Into<Cow<'static, str>>) -> Self {
276 Self::Other(token.into())
277 }
278}
279
280impl AsApiStr for WeatherModel {
281 fn as_api_str(&self) -> Cow<'static, str> {
282 match self {
283 Self::BestMatch => Cow::Borrowed("best_match"),
284 Self::GfsSeamless => Cow::Borrowed("gfs_seamless"),
285 Self::EcmwfIfs025 => Cow::Borrowed("ecmwf_ifs025"),
286 Self::IconSeamless => Cow::Borrowed("icon_seamless"),
287 Self::MeteofranceSeamless => Cow::Borrowed("meteofrance_seamless"),
288 Self::Other(token) => token.clone(),
289 }
290 }
291}
292
293#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
295#[repr(i16)]
296#[non_exhaustive]
297pub enum SoilTemperatureDepth {
298 Cm0 = 0,
300 Cm6 = 6,
302 Cm18 = 18,
304 Cm54 = 54,
306}
307
308impl SoilTemperatureDepth {
309 pub(crate) fn cm(self) -> i16 {
310 self as i16
311 }
312}
313
314#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
316#[repr(i16)]
317#[non_exhaustive]
318pub enum SoilMoistureDepth {
319 Cm0 = 0,
321 Cm1 = 1,
323 Cm3 = 3,
325 Cm9 = 9,
327 Cm27 = 27,
329 Cm81 = 81,
331}
332
333impl SoilMoistureDepth {
334 pub(crate) fn cm(self) -> i16 {
335 self as i16
336 }
337}
338
339#[cfg(test)]
340mod tests {
341 use super::*;
342 use crate::query::AsApiStr;
343
344 #[test]
345 fn archive_model_tokens_are_formatted() {
346 assert_eq!(ArchiveModel::Era5Land.as_api_str(), "era5_land");
347 assert_eq!(ArchiveModel::EcmwfIfs.as_api_str(), "ecmwf_ifs");
348 assert_eq!(ArchiveModel::Cerra.as_api_str(), "cerra");
349 assert_eq!(
350 ArchiveModel::other("custom_archive_model").as_api_str(),
351 "custom_archive_model"
352 );
353 }
354
355 #[test]
356 fn ensemble_model_tokens_are_formatted() {
357 assert_eq!(
358 EnsembleModel::IconSeamlessEps.as_api_str(),
359 "icon_seamless_eps"
360 );
361 assert_eq!(EnsembleModel::IconGlobalEps.as_api_str(), "icon_global_eps");
362 assert_eq!(EnsembleModel::IconEuEps.as_api_str(), "icon_eu_eps");
363 assert_eq!(EnsembleModel::IconD2Eps.as_api_str(), "icon_d2_eps");
364 assert_eq!(
365 EnsembleModel::NcepGefsSeamless.as_api_str(),
366 "ncep_gefs_seamless"
367 );
368 assert_eq!(EnsembleModel::NcepGefs025.as_api_str(), "ncep_gefs025");
369 assert_eq!(EnsembleModel::NcepGefs05.as_api_str(), "ncep_gefs05");
370 assert_eq!(EnsembleModel::NcepAigefs025.as_api_str(), "ncep_aigefs025");
371 assert_eq!(
372 EnsembleModel::EcmwfIfs025Ensemble.as_api_str(),
373 "ecmwf_ifs025_ensemble"
374 );
375 assert_eq!(
376 EnsembleModel::EcmwfAifs025Ensemble.as_api_str(),
377 "ecmwf_aifs025_ensemble"
378 );
379 assert_eq!(
380 EnsembleModel::GemGlobalEnsemble.as_api_str(),
381 "gem_global_ensemble"
382 );
383 assert_eq!(
384 EnsembleModel::BomAccessGlobalEnsemble.as_api_str(),
385 "bom_access_global_ensemble"
386 );
387 assert_eq!(
388 EnsembleModel::UkmoGlobalEnsemble20km.as_api_str(),
389 "ukmo_global_ensemble_20km"
390 );
391 assert_eq!(
392 EnsembleModel::UkmoUkEnsemble2km.as_api_str(),
393 "ukmo_uk_ensemble_2km"
394 );
395 assert_eq!(
396 EnsembleModel::MeteoswissIconCh1Ensemble.as_api_str(),
397 "meteoswiss_icon_ch1_ensemble"
398 );
399 assert_eq!(
400 EnsembleModel::MeteoswissIconCh2Ensemble.as_api_str(),
401 "meteoswiss_icon_ch2_ensemble"
402 );
403 assert_eq!(
404 EnsembleModel::other("custom_ensemble_model").as_api_str(),
405 "custom_ensemble_model"
406 );
407 }
408}