gistools/readers/grib2/sections/_4/
tables3.rs

1#![cfg_attr(feature = "nightly", coverage(off))]
2
3use crate::readers::{
4    TableCategory, grib2_lookup_table42_00, grib2_lookup_table42_01, grib2_lookup_table42_02,
5    grib2_lookup_table42_03, grib2_lookup_table42_04, grib2_lookup_table42_05,
6    grib2_lookup_table42_06, grib2_lookup_table42_07, grib2_lookup_table42_10,
7    grib2_lookup_table42_11, grib2_lookup_table42_12, grib2_lookup_table42_013,
8    grib2_lookup_table42_014, grib2_lookup_table42_015, grib2_lookup_table42_016,
9    grib2_lookup_table42_017, grib2_lookup_table42_018, grib2_lookup_table42_019,
10    grib2_lookup_table42_020, grib2_lookup_table42_20, grib2_lookup_table42_021,
11    grib2_lookup_table42_21, grib2_lookup_table42_022, grib2_lookup_table42_23,
12    grib2_lookup_table42_24, grib2_lookup_table42_25, grib2_lookup_table42_26,
13    grib2_lookup_table42_30, grib2_lookup_table42_31, grib2_lookup_table42_32,
14    grib2_lookup_table42_33, grib2_lookup_table42_34, grib2_lookup_table42_35,
15    grib2_lookup_table42_36, grib2_lookup_table42_40, grib2_lookup_table42_41,
16    grib2_lookup_table42_42, grib2_lookup_table42_43, grib2_lookup_table42_44,
17    grib2_lookup_table42_45, grib2_lookup_table42_46, grib2_lookup_table42_47,
18    grib2_lookup_table42_48, grib2_lookup_table42_49, grib2_lookup_table42_100,
19    grib2_lookup_table42_101, grib2_lookup_table42_102, grib2_lookup_table42_103,
20    grib2_lookup_table42_104, grib2_lookup_table42_0190, grib2_lookup_table42_0191,
21    grib2_lookup_table42_0192, grib2_lookup_table42_410, grib2_lookup_table42_2000,
22    grib2_lookup_table42_2001, grib2_lookup_table42_2002, grib2_lookup_table42_2003,
23    grib2_lookup_table42_10191,
24};
25use alloc::string::String;
26
27/// Type and Unit categorizing
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct TypeAndUnit {
30    /// Type
31    pub r#type: String,
32    /// Unit
33    pub unit: String,
34}
35impl core::fmt::Display for TypeAndUnit {
36    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
37        write!(f, "{} ({})", self.r#type, self.unit)
38    }
39}
40
41fn no_op(_: u8) -> TableCategory {
42    TableCategory {
43        parameter: String::from("Reserved"),
44        units: String::from(""),
45        abbrev: String::from("Reserved"),
46    }
47}
48
49/// GRIB2 - CODE TABLE 4.2: PARAMETER NUMBER BY PRODUCT DISCIPLINE AND PARAMETER CATEGORY
50///
51/// **Created**: 12/07/2023
52/// **Revised**: 12/07/2023
53///
54/// ## Links
55/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-1.shtml)
56///
57/// ## Notes
58/// - By convention, the flux sign is positive if downward.
59/// - When a new parameter is to be added to Code table 4.2 and more than one category applies, the
60///   choice of category should be made base on the intended use of product. The discipline and
61///   category are an important part of any product definition, so it is possible to have the same
62///   parameter name in more than one category. For example, "Water Temperature" in discipline 10
63///   (Oceanographic Products), category 4 (sub-surface properties) is used to reporting water
64///   temperature in the ocean or open sea, and is not the same as "Water temperature" in discipline
65///   1 (Hydrological Products), category 2 (Inland water and sediment properties) which is used for
66///   reporting water temperature in freshwater lakes and rivers.
67///
68/// ## Reads as
69/// `{ [discipline]: { [param catagory]: { TableCategory } }}`
70pub fn grib2_lookup_table42(discipline: u8, category: u8) -> fn(category: u8) -> TableCategory {
71    match discipline {
72        // Product Discipline 0 - Meteorological products
73        0 => {
74            match category {
75                0 => grib2_lookup_table42_00,
76                1 => grib2_lookup_table42_01,
77                2 => grib2_lookup_table42_02,
78                3 => grib2_lookup_table42_03,
79                4 => grib2_lookup_table42_04,
80                5 => grib2_lookup_table42_05,
81                6 => grib2_lookup_table42_06,
82                7 => grib2_lookup_table42_07,
83                13 => grib2_lookup_table42_013,
84                14 => grib2_lookup_table42_014,
85                15 => grib2_lookup_table42_015,
86                16 => grib2_lookup_table42_016,
87                17 => grib2_lookup_table42_017,
88                18 => grib2_lookup_table42_018,
89                19 => grib2_lookup_table42_019,
90                20 => grib2_lookup_table42_020,
91                21 => grib2_lookup_table42_021,
92                22 => grib2_lookup_table42_022,
93                190 => grib2_lookup_table42_0190,
94                191 => grib2_lookup_table42_0191,
95                // 192-254 Reserved for Local Use
96                192 => grib2_lookup_table42_019,
97                _ => no_op,
98            }
99        }
100        // Product Discipline 1, Hydrologic products
101        1 => {
102            match category {
103                0 => grib2_lookup_table42_10,
104                1 => grib2_lookup_table42_11,
105                2 => grib2_lookup_table42_12,
106                // 3-191 Reserved
107                // 192-254 Reserved for Local Use
108                _ => no_op,
109            }
110        }
111        // Product Discipline 2, Land Surface products
112        2 => {
113            match category {
114                0 => grib2_lookup_table42_20,
115                1 => grib2_lookup_table42_21,
116                3 => grib2_lookup_table42_23,
117                4 => grib2_lookup_table42_24,
118                5 => grib2_lookup_table42_25,
119                6 => grib2_lookup_table42_26,
120                // 7-191 Reserved
121                // 192-254 Reserved for Local Use
122                _ => no_op,
123            }
124        }
125        // Product Discipline 3, Space products
126        3 => {
127            match category {
128                0 => grib2_lookup_table42_30,
129                1 => grib2_lookup_table42_31,
130                2 => grib2_lookup_table42_32,
131                3 => grib2_lookup_table42_33,
132                4 => grib2_lookup_table42_34,
133                5 => grib2_lookup_table42_35,
134                6 => grib2_lookup_table42_36,
135                // 7-191 Reserved
136                // 192-254 Reserved for Local Use
137                192 => grib2_lookup_table42_0192,
138                _ => no_op,
139            }
140        }
141        // Product Discipline 4, Space Weather products
142        4 => {
143            match category {
144                0 => grib2_lookup_table42_40,
145                1 => grib2_lookup_table42_41,
146                2 => grib2_lookup_table42_42,
147                3 => grib2_lookup_table42_43,
148                4 => grib2_lookup_table42_44,
149                5 => grib2_lookup_table42_45,
150                6 => grib2_lookup_table42_46,
151                7 => grib2_lookup_table42_47,
152                8 => grib2_lookup_table42_48,
153                9 => grib2_lookup_table42_49,
154                10 => grib2_lookup_table42_410,
155                // 11-191 Reserved
156                // 192-254 Reserved for Local Use
157                _ => no_op,
158            }
159        }
160        // Product Discipline 10, Oceanographic products
161        10 => {
162            match category {
163                0 => grib2_lookup_table42_100,
164                1 => grib2_lookup_table42_101,
165                2 => grib2_lookup_table42_102,
166                3 => grib2_lookup_table42_103,
167                4 => grib2_lookup_table42_104,
168                191 => grib2_lookup_table42_10191,
169                // 192-254 Reserved for Local Use
170                _ => no_op,
171            }
172        }
173        // Product Discipline 20, Health and Socioeconomic impacts
174        20 => {
175            match category {
176                0 => grib2_lookup_table42_2000,
177                1 => grib2_lookup_table42_2001,
178                2 => grib2_lookup_table42_2002,
179                3 => grib2_lookup_table42_2003,
180                // 4-191 Reserved
181                // 192-254 Reserved for Local Use
182                _ => no_op,
183            }
184        }
185        _ => no_op,
186    }
187}
188
189/// # GRIB2 - CODE TABLE 4.3 - TYPE OF GENERATING PROCESS
190///
191/// **Details**:
192/// - **Section**: 4
193/// - **Octet**: 12
194/// - **Revised**: 10/24/2023
195///
196/// **Reserved Ranges**:
197/// - `22-191`: Reserved
198/// - `192-254`: Reserved for Local Use
199///
200/// **Special Value**:
201/// - `255`: Missing
202///
203/// ## Links
204/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-3.shtml)
205///
206/// ## Notes
207/// 1. Code figures `12` and `13` are intended for cases where code figures `0` and `2` may not sufficiently indicate significant post-processing on initial analysis or forecast output.
208/// 2. Analysis increment represents "analysis minus first guess."
209/// 3. Initialized analysis increment represents "initialized analysis minus analysis."
210#[repr(u8)]
211#[allow(missing_docs)]
212#[derive(Debug, Clone, Copy, PartialEq, Eq)]
213pub enum Grib2Table4_3 {
214    Analysis = 0,
215    Initialization = 1,
216    Forecast = 2,
217    BiasCorrectedForecast = 3,
218    EnsembleForecast = 4,
219    ProbabilityForecast = 5,
220    ForecastError = 6,
221    AnalysisError = 7,
222    Observation = 8,
223    Climatological = 9,
224    ProbabilityWeightedForecast = 10,
225    BiasCorrectedEnsembleForecast = 11,
226    PostProcessedAnalysis = 12,
227    PostProcessedForecast = 13,
228    Nowcast = 14,
229    Hindcast = 15,
230    PhysicalRetrieval = 16,
231    RegressionAnalysis = 17,
232    DifferenceBetweenTwoForecasts = 18,
233    FirstGuess = 19,
234    AnalysisIncrement = 20,
235    InitializationIncrementForAnalysis = 21,
236    ForecastConfidenceIndicator = 192,
237    ProbabilityMatchedMean = 193,
238    NeighborhoodProbability = 194,
239    BiasCorrectedAndDownscaledEnsembleForecast = 195,
240    PerturbedAnalysisForEnsembleInitialization = 196,
241    EnsembleAgreementScaleProbability = 197,
242    PostProcessedDeterministicExpertWeightedForecast = 198,
243    EnsembleForecastBasedOnCounting = 199,
244    LocalProbabilityMatchedMean = 200,
245    Missing = 255,
246}
247impl From<u8> for Grib2Table4_3 {
248    fn from(val: u8) -> Self {
249        match val {
250            0 => Self::Analysis,
251            1 => Self::Initialization,
252            2 => Self::Forecast,
253            3 => Self::BiasCorrectedForecast,
254            4 => Self::EnsembleForecast,
255            5 => Self::ProbabilityForecast,
256            6 => Self::ForecastError,
257            7 => Self::AnalysisError,
258            8 => Self::Observation,
259            9 => Self::Climatological,
260            10 => Self::ProbabilityWeightedForecast,
261            11 => Self::BiasCorrectedEnsembleForecast,
262            12 => Self::PostProcessedAnalysis,
263            13 => Self::PostProcessedForecast,
264            14 => Self::Nowcast,
265            15 => Self::Hindcast,
266            16 => Self::PhysicalRetrieval,
267            17 => Self::RegressionAnalysis,
268            18 => Self::DifferenceBetweenTwoForecasts,
269            19 => Self::FirstGuess,
270            20 => Self::AnalysisIncrement,
271            21 => Self::InitializationIncrementForAnalysis,
272            192 => Self::ForecastConfidenceIndicator,
273            193 => Self::ProbabilityMatchedMean,
274            194 => Self::NeighborhoodProbability,
275            195 => Self::BiasCorrectedAndDownscaledEnsembleForecast,
276            196 => Self::PerturbedAnalysisForEnsembleInitialization,
277            197 => Self::EnsembleAgreementScaleProbability,
278            198 => Self::PostProcessedDeterministicExpertWeightedForecast,
279            199 => Self::EnsembleForecastBasedOnCounting,
280            200 => Self::LocalProbabilityMatchedMean,
281            _ => Self::Missing,
282        }
283    }
284}
285impl core::fmt::Display for Grib2Table4_3 {
286    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
287        let desc = match self {
288            Self::Analysis => "Analysis",
289            Self::Initialization => "Initialization",
290            Self::Forecast => "Forecast",
291            Self::BiasCorrectedForecast => "Bias Corrected Forecast",
292            Self::EnsembleForecast => "Ensemble Forecast",
293            Self::ProbabilityForecast => "Probability Forecast",
294            Self::ForecastError => "Forecast Error",
295            Self::AnalysisError => "Analysis Error",
296            Self::Observation => "Observation",
297            Self::Climatological => "Climatological",
298            Self::ProbabilityWeightedForecast => "Probability-Weighted Forecast",
299            Self::BiasCorrectedEnsembleForecast => "Bias-Corrected Ensemble Forecast",
300            Self::PostProcessedAnalysis => "Post-processed Analysis",
301            Self::PostProcessedForecast => "Post-processed Forecast",
302            Self::Nowcast => "Nowcast",
303            Self::Hindcast => "Hindcast",
304            Self::PhysicalRetrieval => "Physical Retrieval",
305            Self::RegressionAnalysis => "Regression Analysis",
306            Self::DifferenceBetweenTwoForecasts => "Difference Between Two Forecasts",
307            Self::FirstGuess => "First guess",
308            Self::AnalysisIncrement => "Analysis increment",
309            Self::InitializationIncrementForAnalysis => "Initialization increment for analysis",
310            Self::ForecastConfidenceIndicator => "Forecast Confidence Indicator",
311            Self::ProbabilityMatchedMean => "Probability-matched Mean",
312            Self::NeighborhoodProbability => "Neighborhood Probability",
313            Self::BiasCorrectedAndDownscaledEnsembleForecast => {
314                "Bias-Corrected and Downscaled Ensemble Forecast"
315            }
316            Self::PerturbedAnalysisForEnsembleInitialization => {
317                "Perturbed Analysis for Ensemble Initialization"
318            }
319            Self::EnsembleAgreementScaleProbability => "Ensemble Agreement Scale Probability",
320            Self::PostProcessedDeterministicExpertWeightedForecast => {
321                "Post-Processed Deterministic-Expert-Weighted Forecast"
322            }
323            Self::EnsembleForecastBasedOnCounting => "Ensemble Forecast Based on Counting",
324            Self::LocalProbabilityMatchedMean => "Local Probability-matched Mean",
325            Self::Missing => "Missing",
326        };
327        f.write_str(desc)
328    }
329}
330
331/// # GRIB2 - CODE TABLE 4.4 - INDICATOR OF UNIT OF TIME RANGE
332///
333/// **Details**:
334/// - **Section**: 4
335/// - **Octet**: 18
336/// - **Created**: 05/12/2005
337///
338/// **Reserved Ranges**:
339/// - `14-191`: Reserved
340/// - `192-254`: Reserved for Local Use
341///
342/// **Special Value**:
343/// - `255`: Missing
344///
345/// ## Links
346/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)
347///
348/// ## Notes
349/// None.
350#[repr(u8)]
351#[allow(missing_docs)]
352#[derive(Debug, Clone, Copy, PartialEq, Eq)]
353pub enum Grib2Table4_4 {
354    Minute = 0,
355    Hour = 1,
356    Day = 2,
357    Month = 3,
358    Year = 4,
359    Decade = 5,
360    Normal = 6,
361    Century = 7,
362    Reserved8 = 8,
363    Reserved9 = 9,
364    Hours3 = 10,
365    Hours6 = 11,
366    Hours12 = 12,
367    Second = 13,
368    Missing = 255,
369}
370impl From<u8> for Grib2Table4_4 {
371    fn from(val: u8) -> Self {
372        match val {
373            0 => Self::Minute,
374            1 => Self::Hour,
375            2 => Self::Day,
376            3 => Self::Month,
377            4 => Self::Year,
378            5 => Self::Decade,
379            6 => Self::Normal,
380            7 => Self::Century,
381            8 => Self::Reserved8,
382            9 => Self::Reserved9,
383            10 => Self::Hours3,
384            11 => Self::Hours6,
385            12 => Self::Hours12,
386            13 => Self::Second,
387            _ => Self::Missing,
388        }
389    }
390}
391impl core::fmt::Display for Grib2Table4_4 {
392    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
393        let desc = match self {
394            Self::Minute => "Minute",
395            Self::Hour => "Hour",
396            Self::Day => "Day",
397            Self::Month => "Month",
398            Self::Year => "Year",
399            Self::Decade => "Decade (10 Years)",
400            Self::Normal => "Normal (30 Years)",
401            Self::Century => "Century (100 Years)",
402            Self::Reserved8 => "Reserved",
403            Self::Reserved9 => "Reserved",
404            Self::Hours3 => "3 Hours",
405            Self::Hours6 => "6 Hours",
406            Self::Hours12 => "12 Hours",
407            Self::Second => "Second",
408            Self::Missing => "Missing",
409        };
410        f.write_str(desc)
411    }
412}
413
414/// GRIB2 - CODE TABLE 4.5 - FIXED SURFACE TYPES AND UNITS
415///
416/// **Details**:
417/// - **Section**: 4
418/// - **Octets**: 23 and 29
419/// - **Revised**: 12/07/2023
420///
421/// **Reserved Ranges**:
422/// - `28-29`: Reserved
423/// - `36-99`: Reserved
424/// - `120-149`: Reserved
425/// - `153-159`: Reserved
426/// - `190-191`: Reserved
427/// - `192-254`: Reserved for Local Use
428///
429/// **Special Value**:
430/// - `255`: Missing
431///
432/// ## Links
433/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)
434///
435/// ## Notes
436/// 1. The Eta vertical coordinate system involves normalizing the pressure at some point on a specific level by the mean sea level pressure at that point.
437/// 2. Hybrid height level can be defined as: z(k)=A(k)+B(k)*orog.
438/// 3. Hybrid pressure level is defined as: p(k)=A(k)+B(k)*sp.
439/// 4. Sigma height level is the height-based terrain-following coordinate.
440/// 5. The soil level represents a model level with varying depths provided by another GRIB message.
441/// 6. The sea-ice level represents varying depths across the model domain.
442/// 7. Ocean level types are defined by property differences from the near-surface.
443/// 8. This level differs from entry 13, which is vertically accumulated from the surface.
444///
445/// This function provides a lookup for GRIB2 fixed surface types and their units
446/// based on the provided code.
447///
448/// # Arguments
449/// * `code` - The code for the fixed surface type (u8).
450///
451/// # Returns
452/// A `TypeAndUnit` struct containing the type and unit of the fixed surface.
453/// Returns "Missing" if the code is 255, "Reserved" for specified reserved ranges,
454/// or "Reserved for Local Use" for local use ranges.
455pub fn grib2_lookup_table4_5(code: u8) -> TypeAndUnit {
456    match code {
457        0 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
458        1 => {
459            TypeAndUnit { r#type: String::from("Ground or Water Surface"), unit: String::from("") }
460        }
461        2 => TypeAndUnit { r#type: String::from("Cloud Base Level"), unit: String::from("") },
462        3 => TypeAndUnit { r#type: String::from("Level of Cloud Tops"), unit: String::from("") },
463        4 => TypeAndUnit {
464            r#type: String::from("Level of 0°C Isotherm"),
465            unit: String::from("°C"),
466        },
467        5 => TypeAndUnit {
468            r#type: String::from("Level of Adiabatic Condensation Lifted from the Surface"),
469            unit: String::from(""),
470        },
471        6 => TypeAndUnit { r#type: String::from("Maximum Wind Level"), unit: String::from("") },
472        7 => TypeAndUnit { r#type: String::from("Tropopause"), unit: String::from("") },
473        8 => TypeAndUnit {
474            r#type: String::from("Nominal Top of the Atmosphere"),
475            unit: String::from(""),
476        },
477        9 => TypeAndUnit { r#type: String::from("Sea Bottom"), unit: String::from("") },
478        10 => TypeAndUnit { r#type: String::from("Entire Atmosphere"), unit: String::from("") },
479        11 => {
480            TypeAndUnit { r#type: String::from("Cumulonimbus Base (CB)"), unit: String::from("m") }
481        }
482        12 => {
483            TypeAndUnit { r#type: String::from("Cumulonimbus Top (CT)"), unit: String::from("m") }
484        }
485        13 => TypeAndUnit {
486            r#type: String::from(
487                "Lowest level where vertically integrated cloud cover exceeds the specified \
488                 percentage",
489            ),
490            unit: String::from("%"),
491        },
492        14 => TypeAndUnit {
493            r#type: String::from("Level of free convection (LFC)"),
494            unit: String::from(""),
495        },
496        15 => TypeAndUnit {
497            r#type: String::from("Convection condensation level (CCL)"),
498            unit: String::from(""),
499        },
500        16 => TypeAndUnit {
501            r#type: String::from("Level of neutral buoyancy or equilibrium (LNB)"),
502            unit: String::from(""),
503        },
504        17 => TypeAndUnit {
505            r#type: String::from("Departure level of the most unstable parcel of air (MUDL)"),
506            unit: String::from(""),
507        },
508        18 => TypeAndUnit {
509            r#type: String::from(
510                "Departure level of a mixed layer parcel of air with specified layer depth",
511            ),
512            unit: String::from("Pa"),
513        },
514        19 => TypeAndUnit {
515            r#type: String::from("Lowest level where cloud cover exceeds the specified percentage"),
516            unit: String::from("%"),
517        },
518        20 => TypeAndUnit { r#type: String::from("Isothermal Level"), unit: String::from("K") },
519        21 => TypeAndUnit {
520            r#type: String::from("Lowest level where mass density exceeds the specified value"),
521            unit: String::from("kg m-3"),
522        },
523        22 => TypeAndUnit {
524            r#type: String::from("Highest level where mass density exceeds the specified value"),
525            unit: String::from("kg m-3"),
526        },
527        23 => TypeAndUnit {
528            r#type: String::from(
529                "Lowest level where air concentration exceeds the specified value",
530            ),
531            unit: String::from("Bq m-3"),
532        },
533        24 => TypeAndUnit {
534            r#type: String::from(
535                "Highest level where air concentration exceeds the specified value",
536            ),
537            unit: String::from("Bq m-3"),
538        },
539        25 => TypeAndUnit {
540            r#type: String::from(
541                "Highest level where radar reflectivity exceeds the specified value",
542            ),
543            unit: String::from("dBZ"),
544        },
545        26 => TypeAndUnit {
546            r#type: String::from("Convective cloud layer base"),
547            unit: String::from("m"),
548        },
549        27 => TypeAndUnit {
550            r#type: String::from("Convective cloud layer top"),
551            unit: String::from("m"),
552        },
553        28..=29 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
554        30 => TypeAndUnit {
555            r#type: String::from("Specified radius from the centre of the Sun"),
556            unit: String::from("m"),
557        },
558        31 => TypeAndUnit { r#type: String::from("Solar photosphere"), unit: String::from("") },
559        32 => TypeAndUnit {
560            r#type: String::from("Ionospheric D-region level"),
561            unit: String::from(""),
562        },
563        33 => TypeAndUnit {
564            r#type: String::from("Ionospheric E-region level"),
565            unit: String::from(""),
566        },
567        34 => TypeAndUnit {
568            r#type: String::from("Ionospheric F1-region level"),
569            unit: String::from(""),
570        },
571        35 => TypeAndUnit {
572            r#type: String::from("Ionospheric F2-region level"),
573            unit: String::from(""),
574        },
575        36..=99 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
576        100 => TypeAndUnit { r#type: String::from("Isobaric Surface"), unit: String::from("Pa") },
577        101 => TypeAndUnit { r#type: String::from("Mean Sea Level"), unit: String::from("") },
578        102 => TypeAndUnit {
579            r#type: String::from("Specific Altitude Above Mean Sea Level"),
580            unit: String::from("m"),
581        },
582        103 => TypeAndUnit {
583            r#type: String::from("Specified Height Level Above Ground"),
584            unit: String::from("m"),
585        },
586        104 => TypeAndUnit { r#type: String::from("Sigma Level"), unit: String::from("") },
587        105 => TypeAndUnit { r#type: String::from("Hybrid Level"), unit: String::from("") },
588        106 => TypeAndUnit {
589            r#type: String::from("Depth Below Land Surface"),
590            unit: String::from("m"),
591        },
592        107 => TypeAndUnit {
593            r#type: String::from("Isentropic (theta) Level"),
594            unit: String::from("K"),
595        },
596        108 => TypeAndUnit {
597            r#type: String::from("Level at Specified Pressure Difference from Ground to Level"),
598            unit: String::from("Pa"),
599        },
600        109 => TypeAndUnit {
601            r#type: String::from("Potential Vorticity Surface"),
602            unit: String::from("K m² kg⁻¹ s⁻¹"),
603        },
604        110 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
605        111 => TypeAndUnit { r#type: String::from("Eta Level"), unit: String::from("") },
606        112 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
607        113 => {
608            TypeAndUnit { r#type: String::from("Logarithmic Hybrid Level"), unit: String::from("") }
609        }
610        114 => TypeAndUnit { r#type: String::from("Snow Level"), unit: String::from("") },
611        115 => TypeAndUnit { r#type: String::from("Sigma height level"), unit: String::from("") },
612        116 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
613        117 => TypeAndUnit { r#type: String::from("Mixed Layer Depth"), unit: String::from("m") },
614        118 => TypeAndUnit { r#type: String::from("Hybrid Height Level"), unit: String::from("") },
615        119 => {
616            TypeAndUnit { r#type: String::from("Hybrid Pressure Level"), unit: String::from("") }
617        }
618        120..=149 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
619        150 => TypeAndUnit {
620            r#type: String::from("Generalized Vertical Height Coordinate"),
621            unit: String::from(""),
622        },
623        151 => TypeAndUnit { r#type: String::from("Soil level"), unit: String::from("") },
624        152 => TypeAndUnit { r#type: String::from("Sea-ice level"), unit: String::from("") },
625        153..=159 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
626        160 => {
627            TypeAndUnit { r#type: String::from("Depth Below Sea Level"), unit: String::from("m") }
628        }
629        161 => TypeAndUnit {
630            r#type: String::from("Depth Below Water Surface"),
631            unit: String::from("m"),
632        },
633        162 => TypeAndUnit { r#type: String::from("Lake or River Bottom"), unit: String::from("") },
634        163 => {
635            TypeAndUnit { r#type: String::from("Bottom Of Sediment Layer"), unit: String::from("") }
636        }
637        164 => TypeAndUnit {
638            r#type: String::from("Bottom Of Thermally Active Sediment Layer"),
639            unit: String::from(""),
640        },
641        165 => TypeAndUnit {
642            r#type: String::from("Bottom Of Sediment Layer Penetrated By Thermal Wave"),
643            unit: String::from(""),
644        },
645        166 => TypeAndUnit { r#type: String::from("Mixing Layer"), unit: String::from("") },
646        167 => TypeAndUnit { r#type: String::from("Bottom of Root Zone"), unit: String::from("") },
647        168 => TypeAndUnit { r#type: String::from("Ocean Model Level"), unit: String::from("") },
648        169 => TypeAndUnit {
649            r#type: String::from(
650                "Ocean level defined by water density (sigma-theta) difference from near-surface \
651                 to level",
652            ),
653            unit: String::from("kg m-3"),
654        },
655        170 => TypeAndUnit {
656            r#type: String::from(
657                "Ocean level defined by water potential temperature difference from near-surface \
658                 to level",
659            ),
660            unit: String::from("K"),
661        },
662        171 => TypeAndUnit {
663            r#type: String::from(
664                "Ocean level defined by vertical eddy diffusivity difference from near-surface to \
665                 level",
666            ),
667            unit: String::from("m² s-1"),
668        },
669        172 => TypeAndUnit {
670            r#type: String::from(
671                "Ocean level defined by water density (rho) difference from near-surface to level",
672            ),
673            unit: String::from("m"),
674        },
675        173 => TypeAndUnit {
676            r#type: String::from("Top of Snow Over Sea Ice on Sea, Lake or River"),
677            unit: String::from(""),
678        },
679        174 => TypeAndUnit {
680            r#type: String::from("Top Surface of Ice on Sea, Lake or River"),
681            unit: String::from(""),
682        },
683        175 => TypeAndUnit {
684            r#type: String::from("Top Surface of Ice, under Snow, on Sea, Lake or River"),
685            unit: String::from(""),
686        },
687        176 => TypeAndUnit {
688            r#type: String::from("Bottom Surface (underside) Ice on Sea, Lake or River"),
689            unit: String::from(""),
690        },
691        177 => TypeAndUnit {
692            r#type: String::from("Deep Soil (of indefinite depth)"),
693            unit: String::from(""),
694        },
695        178 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
696        179 => TypeAndUnit {
697            r#type: String::from("Top Surface of Glacier Ice and Inland Ice"),
698            unit: String::from(""),
699        },
700        180 => TypeAndUnit {
701            r#type: String::from("Deep Inland or Glacier Ice (of indefinite depth)"),
702            unit: String::from(""),
703        },
704        181 => TypeAndUnit {
705            r#type: String::from("Grid Tile Land Fraction as a Model Surface"),
706            unit: String::from(""),
707        },
708        182 => TypeAndUnit {
709            r#type: String::from("Grid Tile Water Fraction as a Model Surface"),
710            unit: String::from(""),
711        },
712        183 => TypeAndUnit {
713            r#type: String::from("Grid Tile Ice Fraction on Sea, Lake or River as a Model Surface"),
714            unit: String::from(""),
715        },
716        184 => TypeAndUnit {
717            r#type: String::from(
718                "Grid Tile Glacier Ice and Inland Ice Fraction as a Model Surface",
719            ),
720            unit: String::from(""),
721        },
722        185 => TypeAndUnit { r#type: String::from("Roof Level"), unit: String::from("") },
723        186 => TypeAndUnit { r#type: String::from("Wall level"), unit: String::from("") },
724        187 => TypeAndUnit { r#type: String::from("Road Level"), unit: String::from("") },
725        188 => {
726            TypeAndUnit { r#type: String::from("Melt pond Top Surface"), unit: String::from("") }
727        }
728        189 => {
729            TypeAndUnit { r#type: String::from("Melt Pond Bottom Surface"), unit: String::from("") }
730        }
731        190..=191 => TypeAndUnit { r#type: String::from("Reserved"), unit: String::from("") },
732        200 => TypeAndUnit {
733            r#type: String::from("Entire atmosphere (considered as a single layer)"),
734            unit: String::from(""),
735        },
736        201 => TypeAndUnit {
737            r#type: String::from("Entire ocean (considered as a single layer)"),
738            unit: String::from(""),
739        },
740        202 => {
741            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
742        }
743        203 => {
744            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
745        }
746        204 => TypeAndUnit {
747            r#type: String::from("Highest tropospheric freezing level"),
748            unit: String::from(""),
749        },
750        205 => {
751            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
752        }
753        206 => TypeAndUnit {
754            r#type: String::from("Grid scale cloud bottom level"),
755            unit: String::from(""),
756        },
757        207 => TypeAndUnit {
758            r#type: String::from("Grid scale cloud top level"),
759            unit: String::from(""),
760        },
761        208 => {
762            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
763        }
764        209 => TypeAndUnit {
765            r#type: String::from("Boundary layer cloud bottom level"),
766            unit: String::from(""),
767        },
768        210 => TypeAndUnit {
769            r#type: String::from("Boundary layer cloud top level"),
770            unit: String::from(""),
771        },
772        211 => TypeAndUnit {
773            r#type: String::from("Boundary layer cloud layer"),
774            unit: String::from(""),
775        },
776        212 => {
777            TypeAndUnit { r#type: String::from("Low cloud bottom level"), unit: String::from("") }
778        }
779        213 => TypeAndUnit { r#type: String::from("Low cloud top level"), unit: String::from("") },
780        214 => TypeAndUnit { r#type: String::from("Low cloud layer"), unit: String::from("") },
781        215 => TypeAndUnit { r#type: String::from("Cloud ceiling"), unit: String::from("") },
782        216 => TypeAndUnit {
783            r#type: String::from("Effective Layer Top Level"),
784            unit: String::from("m"),
785        },
786        217 => TypeAndUnit {
787            r#type: String::from("Effective Layer Bottom Level"),
788            unit: String::from("m"),
789        },
790        218 => TypeAndUnit { r#type: String::from("Effective Layer"), unit: String::from("m") },
791        219 => {
792            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
793        }
794        220 => {
795            TypeAndUnit { r#type: String::from("Planetary Boundary Layer"), unit: String::from("") }
796        }
797        221 => TypeAndUnit {
798            r#type: String::from("Layer Between Two Hybrid Levels"),
799            unit: String::from(""),
800        },
801        222 => TypeAndUnit {
802            r#type: String::from("Middle cloud bottom level"),
803            unit: String::from(""),
804        },
805        223 => {
806            TypeAndUnit { r#type: String::from("Middle cloud top level"), unit: String::from("") }
807        }
808        224 => TypeAndUnit { r#type: String::from("Middle cloud layer"), unit: String::from("") },
809        225..=231 => {
810            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
811        }
812        232 => {
813            TypeAndUnit { r#type: String::from("High cloud bottom level"), unit: String::from("") }
814        }
815        233 => TypeAndUnit { r#type: String::from("High cloud top level"), unit: String::from("") },
816        234 => TypeAndUnit { r#type: String::from("High cloud layer"), unit: String::from("") },
817        235 => TypeAndUnit {
818            r#type: String::from("Ocean Isotherm Level (1/10 °C)"),
819            unit: String::from("°C"),
820        },
821        236 => TypeAndUnit {
822            r#type: String::from("Layer between two depths below ocean surface"),
823            unit: String::from(""),
824        },
825        237 => TypeAndUnit {
826            r#type: String::from("Bottom of Ocean Mixed Layer"),
827            unit: String::from("m"),
828        },
829        238 => TypeAndUnit {
830            r#type: String::from("Bottom of Ocean Isothermal Layer"),
831            unit: String::from("m"),
832        },
833        239 => TypeAndUnit {
834            r#type: String::from("Layer Ocean Surface and 26°C Ocean Isothermal Level"),
835            unit: String::from(""),
836        },
837        240 => TypeAndUnit { r#type: String::from("Ocean Mixed Layer"), unit: String::from("") },
838        241 => {
839            TypeAndUnit { r#type: String::from("Ordered Sequence of Data"), unit: String::from("") }
840        }
841        242 => TypeAndUnit {
842            r#type: String::from("Convective cloud bottom level"),
843            unit: String::from(""),
844        },
845        243 => TypeAndUnit {
846            r#type: String::from("Convective cloud top level"),
847            unit: String::from(""),
848        },
849        244 => {
850            TypeAndUnit { r#type: String::from("Convective cloud layer"), unit: String::from("") }
851        }
852        245 => TypeAndUnit {
853            r#type: String::from("Lowest level of the wet bulb zero"),
854            unit: String::from(""),
855        },
856        246 => TypeAndUnit {
857            r#type: String::from("Maximum equivalent potential temperature level"),
858            unit: String::from(""),
859        },
860        247 => TypeAndUnit { r#type: String::from("Equilibrium level"), unit: String::from("") },
861        248 => TypeAndUnit {
862            r#type: String::from("Shallow convective cloud bottom level"),
863            unit: String::from(""),
864        },
865        249 => TypeAndUnit {
866            r#type: String::from("Shallow convective cloud top level"),
867            unit: String::from(""),
868        },
869        250 => {
870            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
871        }
872        251 => TypeAndUnit {
873            r#type: String::from("Deep convective cloud bottom level"),
874            unit: String::from(""),
875        },
876        252 => TypeAndUnit {
877            r#type: String::from("Deep convective cloud top level"),
878            unit: String::from(""),
879        },
880        253 => TypeAndUnit {
881            r#type: String::from("Lowest bottom level of supercooled liquid water layer"),
882            unit: String::from(""),
883        },
884        254 => TypeAndUnit {
885            r#type: String::from("Highest top level of supercooled liquid water layer"),
886            unit: String::from(""),
887        },
888        255 => TypeAndUnit { r#type: String::from("Missing"), unit: String::from("") },
889        // Handle explicit reserved and local use ranges
890        // The original TS had some 'Reserved' and 'Reserved for Local Use' entries
891        // that fell within the general ranges. I've left those explicit in the match
892        // and covered the remaining parts of the ranges here.
893        192..=199 => {
894            TypeAndUnit { r#type: String::from("Reserved for Local Use"), unit: String::from("") }
895        }
896    }
897}
898
899/// # GRIB2 - CODE TABLE 4.6 - TYPE OF ENSEMBLE FORECAST
900///
901/// **Details**:
902/// - **Section**: 4
903/// - **Octet**: 35 (for product templates 1 and 11)
904/// - **Revised**: 07/22/2010
905///
906/// **Reserved Ranges**:
907/// - `5-191`: Reserved
908/// - `192-254`: Reserved for Local Use
909///
910/// **Special Value**:
911/// - `255`: Missing
912///
913/// ## Links
914/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-6.shtml)
915///
916/// ## Notes
917/// None.
918#[repr(u8)]
919#[allow(missing_docs)]
920#[derive(Debug, Clone, Copy, PartialEq, Eq)]
921pub enum Grib2Table4_6 {
922    UnperturbedHighResolutionControlForecast = 0,
923    UnperturbedLowResolutionControlForecast = 1,
924    NegativelyPerturbedForecast = 2,
925    PositivelyPerturbedForecast = 3,
926    MultiModelForecast = 4,
927    PerturbedEnsembleMember = 192,
928    Missing = 255,
929}
930impl From<u8> for Grib2Table4_6 {
931    fn from(val: u8) -> Self {
932        match val {
933            0 => Self::UnperturbedHighResolutionControlForecast,
934            1 => Self::UnperturbedLowResolutionControlForecast,
935            2 => Self::NegativelyPerturbedForecast,
936            3 => Self::PositivelyPerturbedForecast,
937            4 => Self::MultiModelForecast,
938            192 => Self::PerturbedEnsembleMember,
939            _ => Self::Missing,
940        }
941    }
942}
943impl core::fmt::Display for Grib2Table4_6 {
944    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
945        let desc = match self {
946            Self::UnperturbedHighResolutionControlForecast => {
947                "Unperturbed High-Resolution Control Forecast"
948            }
949            Self::UnperturbedLowResolutionControlForecast => {
950                "Unperturbed Low-Resolution Control Forecast"
951            }
952            Self::NegativelyPerturbedForecast => "Negatively Perturbed Forecast",
953            Self::PositivelyPerturbedForecast => "Positively Perturbed Forecast",
954            Self::MultiModelForecast => "Multi-Model Forecast",
955            Self::PerturbedEnsembleMember => "Perturbed Ensemble Member",
956            Self::Missing => "Missing",
957        };
958        f.write_str(desc)
959    }
960}
961
962/// # GRIB2 - CODE TABLE 4.7 - DERIVED FORECAST
963///
964/// **Details**:
965/// - **Section**: 4
966/// - **Octet**: 35 (for product templates 2-4 and 12-14)
967/// - **Revised**: 07/15/2024
968///
969/// **Reserved Ranges**:
970/// - `11-191`: Reserved
971/// - `192-254`: Reserved for Local Use
972///
973/// **Special Value**:
974/// - `255`: Missing
975///
976/// ## Links
977/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-7.shtml)
978///
979/// ## Notes
980/// 1. Large anomaly index is defined as:
981///    `{(number of members whose anomaly > 0.5 * SD) - (number of members whose anomaly < -0.5 * SD)} / (number of members)`.
982///    SD is the observed climatological standard deviation.
983/// 2. The reference for "minimum of all ensemble members" and "maximum of all ensemble members" is the set of ensemble members
984///    and not a time interval; this differs from Product Definition Template 4.8.
985#[repr(u8)]
986#[allow(missing_docs)]
987#[derive(Debug, Clone, Copy, PartialEq, Eq)]
988pub enum Grib2Table4_7 {
989    UnweightedMeanOfAllMembers = 0,
990    WeightedMeanOfAllMembers = 1,
991    StandardDeviationWithRespectToClusterMean = 2,
992    StandardDeviationWithRespectToClusterMeanNormalized = 3,
993    SpreadOfAllMembers = 4,
994    LargeAnomalyIndexOfAllMembers = 5,
995    UnweightedMeanOfTheClusterMembers = 6,
996    InterquartileRange = 7,
997    MinimumOfAllEnsembleMembers = 8,
998    MaximumOfAllEnsembleMembers = 9,
999    VarianceOfAllEnsembleMembers = 10,
1000    UnweightedModeOfAllMembers = 192,
1001    PercentileValue10OfAllMembers = 193,
1002    PercentileValue50OfAllMembers = 194,
1003    PercentileValue90OfAllMembers = 195,
1004    StatisticallyDecidedWeightsForEachEnsembleMember = 196,
1005    ClimatePercentile = 197,
1006    DeviationOfEnsembleMeanFromDailyClimatology = 198,
1007    ExtremeForecastIndex = 199,
1008    EquallyWeightedMean = 200,
1009    PercentileValue5OfAllMembers = 201,
1010    PercentileValue25OfAllMembers = 202,
1011    PercentileValue75OfAllMembers = 203,
1012    PercentileValue95OfAllMembers = 204,
1013    Missing = 255,
1014}
1015impl From<u8> for Grib2Table4_7 {
1016    fn from(val: u8) -> Self {
1017        match val {
1018            0 => Self::UnweightedMeanOfAllMembers,
1019            1 => Self::WeightedMeanOfAllMembers,
1020            2 => Self::StandardDeviationWithRespectToClusterMean,
1021            3 => Self::StandardDeviationWithRespectToClusterMeanNormalized,
1022            4 => Self::SpreadOfAllMembers,
1023            5 => Self::LargeAnomalyIndexOfAllMembers,
1024            6 => Self::UnweightedMeanOfTheClusterMembers,
1025            7 => Self::InterquartileRange,
1026            8 => Self::MinimumOfAllEnsembleMembers,
1027            9 => Self::MaximumOfAllEnsembleMembers,
1028            10 => Self::VarianceOfAllEnsembleMembers,
1029            192 => Self::UnweightedModeOfAllMembers,
1030            193 => Self::PercentileValue10OfAllMembers,
1031            194 => Self::PercentileValue50OfAllMembers,
1032            195 => Self::PercentileValue90OfAllMembers,
1033            196 => Self::StatisticallyDecidedWeightsForEachEnsembleMember,
1034            197 => Self::ClimatePercentile,
1035            198 => Self::DeviationOfEnsembleMeanFromDailyClimatology,
1036            199 => Self::ExtremeForecastIndex,
1037            200 => Self::EquallyWeightedMean,
1038            201 => Self::PercentileValue5OfAllMembers,
1039            202 => Self::PercentileValue25OfAllMembers,
1040            203 => Self::PercentileValue75OfAllMembers,
1041            204 => Self::PercentileValue95OfAllMembers,
1042            _ => Self::Missing,
1043        }
1044    }
1045}
1046impl core::fmt::Display for Grib2Table4_7 {
1047    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1048        let desc = match self {
1049            Self::UnweightedMeanOfAllMembers => "Unweighted Mean of All Members",
1050            Self::WeightedMeanOfAllMembers => "Weighted Mean of All Members",
1051            Self::StandardDeviationWithRespectToClusterMean => {
1052                "Standard Deviation with respect to Cluster Mean"
1053            }
1054            Self::StandardDeviationWithRespectToClusterMeanNormalized => {
1055                "Standard Deviation with respect to Cluster Mean, Normalized"
1056            }
1057            Self::SpreadOfAllMembers => "Spread of All Members",
1058            Self::LargeAnomalyIndexOfAllMembers => "Large Anomaly Index of All Members",
1059            Self::UnweightedMeanOfTheClusterMembers => "Unweighted Mean of the Cluster Members",
1060            Self::InterquartileRange => {
1061                "Interquartile Range (Range between the 25th and 75th quantile)"
1062            }
1063            Self::MinimumOfAllEnsembleMembers => "Minimum Of All Ensemble Members",
1064            Self::MaximumOfAllEnsembleMembers => "Maximum Of All Ensemble Members",
1065            Self::VarianceOfAllEnsembleMembers => "Variance of all ensemble members",
1066            Self::UnweightedModeOfAllMembers => "Unweighted Mode of All Members",
1067            Self::PercentileValue10OfAllMembers => "Percentile value (10%) of All Members",
1068            Self::PercentileValue50OfAllMembers => "Percentile value (50%) of All Members",
1069            Self::PercentileValue90OfAllMembers => "Percentile value (90%) of All Members",
1070            Self::StatisticallyDecidedWeightsForEachEnsembleMember => {
1071                "Statistically decided weights for each ensemble member"
1072            }
1073            Self::ClimatePercentile => {
1074                "Climate Percentile (percentile values from climate distribution)"
1075            }
1076            Self::DeviationOfEnsembleMeanFromDailyClimatology => {
1077                "Deviation of Ensemble Mean from Daily Climatology"
1078            }
1079            Self::ExtremeForecastIndex => "Extreme Forecast Index",
1080            Self::EquallyWeightedMean => "Equally Weighted Mean",
1081            Self::PercentileValue5OfAllMembers => "Percentile value (5%) of All Members",
1082            Self::PercentileValue25OfAllMembers => "Percentile value (25%) of All Members",
1083            Self::PercentileValue75OfAllMembers => "Percentile value (75%) of All Members",
1084            Self::PercentileValue95OfAllMembers => "Percentile value (95%) of All Members",
1085            Self::Missing => "Missing",
1086        };
1087        f.write_str(desc)
1088    }
1089}
1090
1091/// # GRIB2 - CODE TABLE 4.8 - CLUSTERING METHOD
1092///
1093/// **Details**:
1094/// - **Section**: 4
1095/// - **Octet**: 41 (for product templates 3-4 and 13-14)
1096/// - **Created**: 05/12/2005
1097///
1098/// **Reserved Ranges**:
1099/// - `2-191`: Reserved
1100/// - `192-254`: Reserved for Local Use
1101///
1102/// **Special Value**:
1103/// - `255`: Missing
1104///
1105/// ## Links
1106/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-8.shtml)
1107///
1108/// ## Notes
1109/// None.
1110#[repr(u8)]
1111#[allow(missing_docs)]
1112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1113pub enum Grib2Table4_8 {
1114    AnomalyCorrelation = 0,
1115    RootMeanSquare = 1,
1116    Missing = 255,
1117}
1118impl From<u8> for Grib2Table4_8 {
1119    fn from(val: u8) -> Self {
1120        match val {
1121            0 => Self::AnomalyCorrelation,
1122            1 => Self::RootMeanSquare,
1123            _ => Self::Missing,
1124        }
1125    }
1126}
1127impl core::fmt::Display for Grib2Table4_8 {
1128    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1129        let desc = match self {
1130            Self::AnomalyCorrelation => "Anomoly Correlation",
1131            Self::RootMeanSquare => "Root Mean Square",
1132            Self::Missing => "Missing",
1133        };
1134        f.write_str(desc)
1135    }
1136}
1137
1138/// # GRIB2 - CODE TABLE 4.9 - PROBABILITY TYPE
1139///
1140/// **Details**:
1141/// - **Section**: 4
1142/// - **Octet**: 37 (for product templates 5 and 9)
1143/// - **Revised**: 07/15/2024
1144///
1145/// **Reserved Ranges**:
1146/// - `10-191`: Reserved
1147/// - `192-254`: Reserved for Local Use
1148///
1149/// **Special Value**:
1150/// - `255`: Missing
1151///
1152/// ## Links
1153/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-9.shtml)
1154///
1155/// ## Notes
1156/// 1. Above normal, near normal, and below normal are defined as three equiprobable categories based on climatology at each point.
1157///    The methodology and reference climatology are unspecified and should be documented by the data producer.
1158/// 2. Product definition templates using this table may include octets for lower and upper limits. For categorical probabilities
1159///    (e.g., below, near, or above normal), these octets are set to "all ones" (missing).
1160/// 3. Scale Factor and Scaled Values for lower/upper limits must be set to missing for entry `9`.
1161///    This is primarily for categorical boolean counts.
1162#[repr(u8)]
1163#[allow(missing_docs)]
1164#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1165pub enum Grib2Table4_9 {
1166    ProbabilityOfEventBelowLowerLimit = 0,
1167    ProbabilityOfEventAboveUpperLimit = 1,
1168    ProbabilityOfEventBetweenUpperAndLowerLimits = 2,
1169    ProbabilityOfEventAboveLowerLimit = 3,
1170    ProbabilityOfEventBelowUpperLimit = 4,
1171    ProbabilityOfEventEqualToLowerLimit = 5,
1172    ProbabilityOfEventInAboveNormalCategory = 6,
1173    ProbabilityOfEventInNearNormalCategory = 7,
1174    ProbabilityOfEventInBelowNormalCategory = 8,
1175    ProbabilityBasedOnCountsOfCategoricalBoolean = 9,
1176    Missing = 255,
1177}
1178impl From<u8> for Grib2Table4_9 {
1179    fn from(val: u8) -> Self {
1180        match val {
1181            0 => Self::ProbabilityOfEventBelowLowerLimit,
1182            1 => Self::ProbabilityOfEventAboveUpperLimit,
1183            2 => Self::ProbabilityOfEventBetweenUpperAndLowerLimits,
1184            3 => Self::ProbabilityOfEventAboveLowerLimit,
1185            4 => Self::ProbabilityOfEventBelowUpperLimit,
1186            5 => Self::ProbabilityOfEventEqualToLowerLimit,
1187            6 => Self::ProbabilityOfEventInAboveNormalCategory,
1188            7 => Self::ProbabilityOfEventInNearNormalCategory,
1189            8 => Self::ProbabilityOfEventInBelowNormalCategory,
1190            9 => Self::ProbabilityBasedOnCountsOfCategoricalBoolean,
1191            _ => Self::Missing,
1192        }
1193    }
1194}
1195impl core::fmt::Display for Grib2Table4_9 {
1196    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1197        let desc = match self {
1198            Self::ProbabilityOfEventBelowLowerLimit => "Probability of event below lower limit",
1199            Self::ProbabilityOfEventAboveUpperLimit => "Probability of event above upper limit",
1200            Self::ProbabilityOfEventBetweenUpperAndLowerLimits => {
1201                "Probability of event between upper and lower limits (range includes lower limit \
1202                 but not the upper limit)"
1203            }
1204            Self::ProbabilityOfEventAboveLowerLimit => "Probability of event above lower limit",
1205            Self::ProbabilityOfEventBelowUpperLimit => "Probability of event below upper limit",
1206            Self::ProbabilityOfEventEqualToLowerLimit => {
1207                "Probability of event equal to lower limit"
1208            }
1209            Self::ProbabilityOfEventInAboveNormalCategory => {
1210                "Probability of event in above normal category"
1211            }
1212            Self::ProbabilityOfEventInNearNormalCategory => {
1213                "Probability of event in near normal category"
1214            }
1215            Self::ProbabilityOfEventInBelowNormalCategory => {
1216                "Probability of event in below normal category"
1217            }
1218            Self::ProbabilityBasedOnCountsOfCategoricalBoolean => {
1219                "Probability based on counts of categorical boolean"
1220            }
1221            Self::Missing => "Missing",
1222        };
1223        f.write_str(desc)
1224    }
1225}
1226
1227/// # GRIB2 - CODE TABLE 4.10 - TYPE OF STATISTICAL PROCESSING
1228///
1229/// **Details**:
1230/// - **Section**: 4
1231/// - **Octet**: 47 (for product template 8)
1232/// - **Revised**: 10/24/2023
1233///
1234/// **Reserved Ranges**:
1235/// - `14-99`: Reserved
1236/// - `103-191`: Reserved
1237/// - `192-254`: Reserved for Local Use
1238///
1239/// **Special Value**:
1240/// - `255`: Missing
1241///
1242/// ## Links
1243/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-10.shtml)
1244///
1245/// ## Notes
1246/// 1. The original data value has units of Code Table 4.2 multiplied by seconds, unless otherwise specified.
1247/// 2. Covariance (Code 7) has squared units of Code Table 4.2.
1248/// 3. Ratio (Code 9) is a non-dimensional number without units.
1249/// 4. For code number 102, the drought index is defined by discipline 0, parameter category 22, and the corresponding parameter number.
1250#[repr(u8)]
1251#[allow(missing_docs)]
1252#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1253pub enum Grib2Table4_10 {
1254    Average = 0,
1255    Accumulation = 1,
1256    Maximum = 2,
1257    Minimum = 3,
1258    DifferenceEndMinusBeginning = 4,
1259    RootMeanSquare = 5,
1260    StandardDeviation = 6,
1261    Covariance = 7,
1262    DifferenceBeginningMinusEnd = 8,
1263    Ratio = 9,
1264    StandardizedAnomaly = 10,
1265    Summation = 11,
1266    ReturnPeriod = 12,
1267    Median = 13,
1268    Severity = 100,
1269    Mode = 101,
1270    IndexProcessing = 102,
1271    ClimatologicalMeanValue = 192,
1272    AverageOfNForecasts = 193,
1273    AverageOfNUninitializedAnalyses = 194,
1274    AverageOfForecastAccumulations24Hour = 195,
1275    AverageOfSuccessiveForecastAccumulations = 196,
1276    AverageOfForecastAverages24Hour = 197,
1277    AverageOfSuccessiveForecastAverages = 198,
1278    ClimatologicalAverageOfNAnalyses = 199,
1279    ClimatologicalAverageOfNForecasts = 200,
1280    ClimatologicalRootMeanSquareDifferenceBetweenNForecastsAndTheirVerifyingAnalyses = 201,
1281    ClimatologicalStandardDeviationOfNForecasts = 202,
1282    ClimatologicalStandardDeviationOfNAnalyses = 203,
1283    AverageOfForecastAccumulations6Hour = 204,
1284    AverageOfForecastAverages6Hour = 205,
1285    AverageOfForecastAccumulations12Hour = 206,
1286    AverageOfForecastAverages12Hour = 207,
1287    Variance = 208,
1288    Coefficient = 209,
1289    Missing = 255,
1290}
1291impl From<u8> for Grib2Table4_10 {
1292    fn from(val: u8) -> Self {
1293        match val {
1294            0 => Self::Average,
1295            1 => Self::Accumulation,
1296            2 => Self::Maximum,
1297            3 => Self::Minimum,
1298            4 => Self::DifferenceEndMinusBeginning,
1299            5 => Self::RootMeanSquare,
1300            6 => Self::StandardDeviation,
1301            7 => Self::Covariance,
1302            8 => Self::DifferenceBeginningMinusEnd,
1303            9 => Self::Ratio,
1304            10 => Self::StandardizedAnomaly,
1305            11 => Self::Summation,
1306            12 => Self::ReturnPeriod,
1307            13 => Self::Median,
1308            100 => Self::Severity,
1309            101 => Self::Mode,
1310            102 => Self::IndexProcessing,
1311            192 => Self::ClimatologicalMeanValue,
1312            193 => Self::AverageOfNForecasts,
1313            194 => Self::AverageOfNUninitializedAnalyses,
1314            195 => Self::AverageOfForecastAccumulations24Hour,
1315            196 => Self::AverageOfSuccessiveForecastAccumulations,
1316            197 => Self::AverageOfForecastAverages24Hour,
1317            198 => Self::AverageOfSuccessiveForecastAverages,
1318            199 => Self::ClimatologicalAverageOfNAnalyses,
1319            200 => Self::ClimatologicalAverageOfNForecasts,
1320            201 => Self::ClimatologicalRootMeanSquareDifferenceBetweenNForecastsAndTheirVerifyingAnalyses,
1321            202 => Self::ClimatologicalStandardDeviationOfNForecasts,
1322            203 => Self::ClimatologicalStandardDeviationOfNAnalyses,
1323            204 => Self::AverageOfForecastAccumulations6Hour,
1324            205 => Self::AverageOfForecastAverages6Hour,
1325            206 => Self::AverageOfForecastAccumulations12Hour,
1326            207 => Self::AverageOfForecastAverages12Hour,
1327            208 => Self::Variance,
1328            209 => Self::Coefficient,
1329            _ => Self::Missing,
1330        }
1331    }
1332}
1333impl core::fmt::Display for Grib2Table4_10 {
1334    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1335        let desc = match self {
1336            Self::Average => "Average",
1337            Self::Accumulation => "Accumulation",
1338            Self::Maximum => "Maximum",
1339            Self::Minimum => "Minimum",
1340            Self::DifferenceEndMinusBeginning => "Difference (value at the end of the time range minus value at the beginning)",
1341            Self::RootMeanSquare => "Root Mean Square",
1342            Self::StandardDeviation => "Standard Deviation",
1343            Self::Covariance => "Covariance (temporal variance)",
1344            Self::DifferenceBeginningMinusEnd => "Difference (value at the beginning of the time range minus value at the end)",
1345            Self::Ratio => "Ratio",
1346            Self::StandardizedAnomaly => "Standardized Anomaly",
1347            Self::Summation => "Summation",
1348            Self::ReturnPeriod => "Return period",
1349            Self::Median => "Median",
1350            Self::Severity => "Severity",
1351            Self::Mode => "Mode",
1352            Self::IndexProcessing => "Index processing",
1353            Self::ClimatologicalMeanValue => "Climatological Mean Value",
1354            Self::AverageOfNForecasts => "Average of N forecasts (or initialized analyses)",
1355            Self::AverageOfNUninitializedAnalyses => "Average of N uninitialized analyses",
1356            Self::AverageOfForecastAccumulations24Hour => "Average of forecast accumulations (24-hour intervals)",
1357            Self::AverageOfSuccessiveForecastAccumulations => "Average of successive forecast accumulations",
1358            Self::AverageOfForecastAverages24Hour => "Average of forecast averages (24-hour intervals)",
1359            Self::AverageOfSuccessiveForecastAverages => "Average of successive forecast averages",
1360            Self::ClimatologicalAverageOfNAnalyses => "Climatological Average of N analyses",
1361            Self::ClimatologicalAverageOfNForecasts => "Climatological Average of N forecasts",
1362            Self::ClimatologicalRootMeanSquareDifferenceBetweenNForecastsAndTheirVerifyingAnalyses => {
1363                "Climatological Root Mean Square difference between N forecasts and their verifying analyses"
1364            }
1365            Self::ClimatologicalStandardDeviationOfNForecasts => {
1366                "Climatological Standard Deviation of N forecasts"
1367            }
1368            Self::ClimatologicalStandardDeviationOfNAnalyses => {
1369                "Climatological Standard Deviation of N analyses"
1370            }
1371            Self::AverageOfForecastAccumulations6Hour => "Average of forecast accumulations (6-hour intervals)",
1372            Self::AverageOfForecastAverages6Hour => "Average of forecast averages (6-hour intervals)",
1373            Self::AverageOfForecastAccumulations12Hour => "Average of forecast accumulations (12-hour intervals)",
1374            Self::AverageOfForecastAverages12Hour => "Average of forecast averages (12-hour intervals)",
1375            Self::Variance => "Variance",
1376            Self::Coefficient => "Coefficient",
1377            Self::Missing => "Missing",
1378        };
1379        f.write_str(desc)
1380    }
1381}
1382
1383/// # GRIB2 - CODE TABLE 4.11 - TYPE OF TIME INTERVALS
1384///
1385/// **Details**:
1386/// - **Section**: 4
1387/// - **Octet**: 48 (for product templates 8)
1388/// - **Revised**: 12/21/2011
1389///
1390/// **Reserved Ranges**:
1391/// - `6-191`: Reserved
1392/// - `192-254`: Reserved for Local Use
1393///
1394/// **Special Value**:
1395/// - `255`: Missing
1396///
1397/// ## Links
1398/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)
1399///
1400/// ## Notes
1401/// 1. Code figure `5` applies when a single time subinterval is used to calculate the statistically processed field.
1402///    The exact starting and ending times of the subinterval are not specified but are inclusively within the overall interval.
1403#[repr(u8)]
1404#[allow(missing_docs)]
1405#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1406pub enum Grib2Table4_11 {
1407    Reserved = 0,
1408    SuccessiveTimesProcessedHaveSameForecastTimeStartOfForecastIsIncremented = 1,
1409    SuccessiveTimesProcessedHaveSameStartTimeOfForecastForecastTimeIsIncremented = 2,
1410    SuccessiveTimesProcessedHaveStartTimeOfForecastIncrementedAndForecastTimeDecrementedSoThatValidTimeRemainsConstant =
1411        3,
1412    SuccessiveTimesProcessedHaveStartTimeOfForecastDecrementedAndForecastTimeIncrementedSoThatValidTimeRemainsConstant =
1413        4,
1414    FloatingSubintervalOfTimeBetweenForecastTimeAndEndOfOverallTimeInterval = 5,
1415    Missing = 255,
1416}
1417impl From<u8> for Grib2Table4_11 {
1418    fn from(val: u8) -> Self {
1419        match val {
1420            0 => Self::Reserved,
1421            1 => Self::SuccessiveTimesProcessedHaveSameForecastTimeStartOfForecastIsIncremented,
1422            2 => Self::SuccessiveTimesProcessedHaveSameStartTimeOfForecastForecastTimeIsIncremented,
1423            3 => Self::SuccessiveTimesProcessedHaveStartTimeOfForecastIncrementedAndForecastTimeDecrementedSoThatValidTimeRemainsConstant,
1424            4 => Self::SuccessiveTimesProcessedHaveStartTimeOfForecastDecrementedAndForecastTimeIncrementedSoThatValidTimeRemainsConstant,
1425            5 => Self::FloatingSubintervalOfTimeBetweenForecastTimeAndEndOfOverallTimeInterval,
1426            _ => Self::Missing,
1427        }
1428    }
1429}
1430impl core::fmt::Display for Grib2Table4_11 {
1431    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1432        let desc = match self {
1433            Self::Reserved => "Reserved",
1434            Self::SuccessiveTimesProcessedHaveSameForecastTimeStartOfForecastIsIncremented => {
1435                "Successive times processed have same forecast time, start time of forecast is incremented."
1436            }
1437            Self::SuccessiveTimesProcessedHaveSameStartTimeOfForecastForecastTimeIsIncremented => {
1438                "Successive times processed have same start time of forecast, forecast time is incremented."
1439            }
1440            Self::SuccessiveTimesProcessedHaveStartTimeOfForecastIncrementedAndForecastTimeDecrementedSoThatValidTimeRemainsConstant => {
1441                "Successive times processed have start time of forecast incremented and forecast time decremented so that valid time remains constant."
1442            }
1443            Self::SuccessiveTimesProcessedHaveStartTimeOfForecastDecrementedAndForecastTimeIncrementedSoThatValidTimeRemainsConstant => {
1444                "Successive times processed have start time of forecast decremented and forecast time incremented so that valid time remains constant."
1445            }
1446            Self::FloatingSubintervalOfTimeBetweenForecastTimeAndEndOfOverallTimeInterval => {
1447                "Floating subinterval of time between forecast time and end of overall time interval."
1448            }
1449            Self::Missing => "Missing",
1450        };
1451        f.write_str(desc)
1452    }
1453}
1454
1455/// # GRIB2 - CODE TABLE 4.12 - OPERATING MODE
1456///
1457/// **Details**:
1458/// - **Section**: 4
1459/// - **Octet**: 31 (for product template 20)
1460/// - **Created**: 05/16/2005
1461///
1462/// **Reserved Ranges**:
1463/// - `3-191`: Reserved
1464/// - `192-254`: Reserved for Local Use
1465///
1466/// **Special Value**:
1467/// - `255`: Missing
1468///
1469/// ## Links
1470/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-12.shtml)
1471///
1472/// ## Notes
1473/// None.
1474#[repr(u8)]
1475#[allow(missing_docs)]
1476#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1477pub enum Grib2Table4_12 {
1478    MaintenanceMode = 0,
1479    ClearAir = 1,
1480    Precipitation = 2,
1481    Missing = 255,
1482}
1483impl From<u8> for Grib2Table4_12 {
1484    fn from(val: u8) -> Self {
1485        match val {
1486            0 => Self::MaintenanceMode,
1487            1 => Self::ClearAir,
1488            2 => Self::Precipitation,
1489            _ => Self::Missing,
1490        }
1491    }
1492}
1493impl core::fmt::Display for Grib2Table4_12 {
1494    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1495        let desc = match self {
1496            Self::MaintenanceMode => "Maintenance Mode",
1497            Self::ClearAir => "Clear Air",
1498            Self::Precipitation => "Precipitation",
1499            Self::Missing => "Missing",
1500        };
1501        f.write_str(desc)
1502    }
1503}
1504
1505/// # GRIB2 - CODE TABLE 4.13 - QUALITY CONTROL INDICATOR
1506///
1507/// **Details**:
1508/// - **Section**: 4
1509/// - **Octet**: 33 (for Product Definition Template 20)
1510/// - **Created**: 05/16/2005
1511///
1512/// **Reserved Ranges**:
1513/// - `2-191`: Reserved
1514/// - `192-254`: Reserved for Local Use
1515///
1516/// **Special Value**:
1517/// - `255`: Missing
1518///
1519/// ## Links
1520/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-13.shtml)
1521///
1522/// ## Notes
1523/// None.
1524#[repr(u8)]
1525#[allow(missing_docs)]
1526#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1527pub enum Grib2Table4_13 {
1528    NoQualityControlApplied = 0,
1529    QualityControlApplied = 1,
1530    Missing = 255,
1531}
1532impl From<u8> for Grib2Table4_13 {
1533    fn from(val: u8) -> Self {
1534        match val {
1535            0 => Self::NoQualityControlApplied,
1536            1 => Self::QualityControlApplied,
1537            _ => Self::Missing,
1538        }
1539    }
1540}
1541impl core::fmt::Display for Grib2Table4_13 {
1542    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1543        let desc = match self {
1544            Self::NoQualityControlApplied => "No Quality Control Applied",
1545            Self::QualityControlApplied => "Quality Control Applied",
1546            Self::Missing => "Missing",
1547        };
1548        f.write_str(desc)
1549    }
1550}
1551
1552/// # GRIB2 - CODE TABLE 4.14 - CLUTTER FILTER INDICATOR
1553///
1554/// **Details**:
1555/// - **Section**: 4
1556/// - **Octet**: 34 (for product template 20)
1557/// - **Created**: 05/16/2005
1558///
1559/// **Reserved Ranges**:
1560/// - `2-191`: Reserved
1561/// - `192-254`: Reserved for Local Use
1562///
1563/// **Special Value**:
1564/// - `255`: Missing
1565///
1566/// ## Links
1567/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-14.shtml)
1568///
1569/// ## Notes
1570/// None.
1571#[repr(u8)]
1572#[allow(missing_docs)]
1573#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1574pub enum Grib2Table4_14 {
1575    NoClutterFilterUsed = 0,
1576    ClutterFilterUsed = 1,
1577    Missing = 255,
1578}
1579impl From<u8> for Grib2Table4_14 {
1580    fn from(val: u8) -> Self {
1581        match val {
1582            0 => Self::NoClutterFilterUsed,
1583            1 => Self::ClutterFilterUsed,
1584            _ => Self::Missing,
1585        }
1586    }
1587}
1588impl core::fmt::Display for Grib2Table4_14 {
1589    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1590        let desc = match self {
1591            Self::NoClutterFilterUsed => "No Clutter Filter Used",
1592            Self::ClutterFilterUsed => "Clutter Filter Used",
1593            Self::Missing => "Missing",
1594        };
1595        f.write_str(desc)
1596    }
1597}
1598
1599/// # GRIB2 - CODE TABLE 4.15 - TYPE OF SPATIAL PROCESSING
1600///
1601/// **Details**:
1602/// - **Created**: 12/10/2009
1603///
1604/// **Reserved Ranges**:
1605/// - `7-191`: Reserved
1606/// - `192-254`: Reserved for Local Use
1607///
1608/// **Special Value**:
1609/// - `255`: Missing
1610///
1611/// ## Links
1612/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-15.shtml)
1613///
1614/// ## Notes
1615/// 1. This method assumes that each field represents box averages/maxima/minima extending halfway to neighboring grid points.
1616/// 2. Budget interpolation quasi-conserves area averages, useful for budget fields such as precipitation. It averages bilinearly
1617///    interpolated values within a square array of points distributed in each output grid box.
1618/// 3. Neighbor-budget interpolation performs a budget interpolation at the grid point nearest to the nominal grid point.
1619#[repr(u8)]
1620#[allow(missing_docs)]
1621#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1622pub enum Grib2Table4_15 {
1623    DataCalculatedDirectlyFromSourceGridNoInterpolation = 0,
1624    BilinearInterpolation = 1,
1625    BicubicInterpolation = 2,
1626    NearestNeighbor = 3,
1627    BudgetInterpolation = 4,
1628    SpectralInterpolation = 5,
1629    NeighborBudgetInterpolation = 6,
1630    Missing = 255,
1631}
1632impl From<u8> for Grib2Table4_15 {
1633    fn from(val: u8) -> Self {
1634        match val {
1635            0 => Self::DataCalculatedDirectlyFromSourceGridNoInterpolation,
1636            1 => Self::BilinearInterpolation,
1637            2 => Self::BicubicInterpolation,
1638            3 => Self::NearestNeighbor,
1639            4 => Self::BudgetInterpolation,
1640            5 => Self::SpectralInterpolation,
1641            6 => Self::NeighborBudgetInterpolation,
1642            _ => Self::Missing,
1643        }
1644    }
1645}
1646impl core::fmt::Display for Grib2Table4_15 {
1647    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1648        let desc = match self {
1649            Self::DataCalculatedDirectlyFromSourceGridNoInterpolation => {
1650                "Data is calculated directly from the source grid with no interpolation"
1651            }
1652            Self::BilinearInterpolation => {
1653                "Bilinear interpolation using the 4 source grid-point values surrounding the \
1654                 nominal grid-point"
1655            }
1656            Self::BicubicInterpolation => {
1657                "Bicubic interpolation using the 4 source grid-point values surrounding the \
1658                 nominal grid-point"
1659            }
1660            Self::NearestNeighbor => {
1661                "Using the value from the source grid-point which is nearest to the nominal \
1662                 grid-point"
1663            }
1664            Self::BudgetInterpolation => {
1665                "Budget interpolation using the 4 source grid-point values surrounding the nominal \
1666                 grid-point"
1667            }
1668            Self::SpectralInterpolation => {
1669                "Spectral interpolation using the 4 source grid-point values surrounding the \
1670                 nominal grid-point"
1671            }
1672            Self::NeighborBudgetInterpolation => {
1673                "Neighbor-budget interpolation using the 4 source grid-point values surrounding \
1674                 the nominal grid-point"
1675            }
1676            Self::Missing => "Missing",
1677        };
1678        f.write_str(desc)
1679    }
1680}
1681
1682/// # GRIB2 - CODE TABLE 4.16 - QUALITY VALUE ASSOCIATED WITH PARAMETER
1683///
1684/// **Details**:
1685/// - **Section**: 4
1686/// - **Octet**: 14 (for product templates 35)
1687/// - **Revised**: 07/01/2022
1688///
1689/// **Reserved Ranges**:
1690/// - `6-191`: Reserved
1691/// - `192-254`: Reserved for Local Use
1692///
1693/// **Special Value**:
1694/// - `255`: Missing
1695///
1696/// ## Links
1697/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-16.shtml)
1698///
1699/// ## Notes
1700/// 1. When a non-missing value is used, it represents a quality value associated with the parameter defined by octets 10 and 11 of the product definition template.
1701/// 2. For "Confidence index" (Code 0), the value ranges from 0 (no confidence) to 1 (maximal confidence) and is non-dimensional.
1702/// 3. "Quality indicator" (Code 1) values are defined by Code Table 4.244.
1703/// 4. "Correlation of Product with used Calibration Product" (Code 2) is a non-dimensional value without units.
1704/// 5. For "Standard deviation" (Code 3) and "Random error" (Code 4), the value uses the same units as the parameter defined by octets 10 and 11.
1705#[repr(u8)]
1706#[allow(missing_docs)]
1707#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1708pub enum Grib2Table4_16 {
1709    ConfidenceIndex = 0,
1710    QualityIndicator = 1,
1711    CorrelationOfProductWithUsedCalibrationProduct = 2,
1712    StandardDeviation = 3,
1713    RandomError = 4,
1714    Probability = 5,
1715    Missing = 255,
1716}
1717impl From<u8> for Grib2Table4_16 {
1718    fn from(val: u8) -> Self {
1719        match val {
1720            0 => Self::ConfidenceIndex,
1721            1 => Self::QualityIndicator,
1722            2 => Self::CorrelationOfProductWithUsedCalibrationProduct,
1723            3 => Self::StandardDeviation,
1724            4 => Self::RandomError,
1725            5 => Self::Probability,
1726            _ => Self::Missing,
1727        }
1728    }
1729}
1730impl core::fmt::Display for Grib2Table4_16 {
1731    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1732        let desc = match self {
1733            Self::ConfidenceIndex => "Confidence index",
1734            Self::QualityIndicator => "Quality indicator",
1735            Self::CorrelationOfProductWithUsedCalibrationProduct => {
1736                "Correlation of Product with used Calibration Product"
1737            }
1738            Self::StandardDeviation => "Standard deviation",
1739            Self::RandomError => "Random error",
1740            Self::Probability => "Probability",
1741            Self::Missing => "Missing",
1742        };
1743        f.write_str(desc)
1744    }
1745}
1746
1747/// # GRIB2 - CODE TABLE 4.91 - TYPE OF INTERVAL
1748///
1749/// **Details**:
1750/// - **Created**: 12/21/2011
1751///
1752/// **Reserved Ranges**:
1753/// - `12-191`: Reserved
1754/// - `192-254`: Reserved for Local Use
1755///
1756/// **Special Value**:
1757/// - `255`: Missing
1758///
1759/// ## Links
1760/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)
1761///
1762/// ## Notes
1763/// None.
1764#[repr(u8)]
1765#[allow(missing_docs)]
1766#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1767pub enum Grib2Table4_91 {
1768    SmallerThanFirstLimit = 0,
1769    GreaterThanSecondLimit = 1,
1770    BetweenFirstAndSecondLimitIncludesFirstButNotSecond = 2,
1771    GreaterThanFirstLimit = 3,
1772    SmallerThanSecondLimit = 4,
1773    SmallerOrEqualFirstLimit = 5,
1774    GreaterOrEqualSecondLimit = 6,
1775    BetweenFirstAndSecondLimitIncludesBoth = 7,
1776    GreaterOrEqualFirstLimit = 8,
1777    SmallerOrEqualSecondLimit = 9,
1778    BetweenFirstAndSecondLimitIncludesSecondButNotFirst = 10,
1779    EqualToFirstLimit = 11,
1780    Missing = 255,
1781}
1782impl From<u8> for Grib2Table4_91 {
1783    fn from(val: u8) -> Self {
1784        match val {
1785            0 => Self::SmallerThanFirstLimit,
1786            1 => Self::GreaterThanSecondLimit,
1787            2 => Self::BetweenFirstAndSecondLimitIncludesFirstButNotSecond,
1788            3 => Self::GreaterThanFirstLimit,
1789            4 => Self::SmallerThanSecondLimit,
1790            5 => Self::SmallerOrEqualFirstLimit,
1791            6 => Self::GreaterOrEqualSecondLimit,
1792            7 => Self::BetweenFirstAndSecondLimitIncludesBoth,
1793            8 => Self::GreaterOrEqualFirstLimit,
1794            9 => Self::SmallerOrEqualSecondLimit,
1795            10 => Self::BetweenFirstAndSecondLimitIncludesSecondButNotFirst,
1796            11 => Self::EqualToFirstLimit,
1797            _ => Self::Missing,
1798        }
1799    }
1800}
1801impl core::fmt::Display for Grib2Table4_91 {
1802    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1803        let desc = match self {
1804            Self::SmallerThanFirstLimit => "Smaller than first limit",
1805            Self::GreaterThanSecondLimit => "Greater than second limit",
1806            Self::BetweenFirstAndSecondLimitIncludesFirstButNotSecond => {
1807                "Between first and second limit (includes first limit but not the second)"
1808            }
1809            Self::GreaterThanFirstLimit => "Greater than first limit",
1810            Self::SmallerThanSecondLimit => "Smaller than second limit",
1811            Self::SmallerOrEqualFirstLimit => "Smaller or equal first limit",
1812            Self::GreaterOrEqualSecondLimit => "Greater or equal second limit",
1813            Self::BetweenFirstAndSecondLimitIncludesBoth => {
1814                "Between first and second limit (includes both first and second limits)"
1815            }
1816            Self::GreaterOrEqualFirstLimit => "Greater or equal first limit",
1817            Self::SmallerOrEqualSecondLimit => "Smaller or equal second limit",
1818            Self::BetweenFirstAndSecondLimitIncludesSecondButNotFirst => {
1819                "Between first and second limit (includes second limit but not the first)"
1820            }
1821            Self::EqualToFirstLimit => "Equal to first limit",
1822            Self::Missing => "Missing",
1823        };
1824        f.write_str(desc)
1825    }
1826}
1827
1828/// # GRIB2 - CODE TABLE 4.100 - TYPE OF REFERENCE DATASET
1829///
1830/// **Details**:
1831/// - **Created**: 10/24/2023
1832///
1833/// **Reserved Ranges**:
1834/// - `6-191`: Reserved
1835/// - `192-254`: Reserved for Local Use
1836///
1837/// **Special Value**:
1838/// - `255`: Missing
1839///
1840/// ## Links
1841/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-100.shtml)
1842///
1843/// ## Notes
1844/// None.
1845#[repr(u8)]
1846#[allow(missing_docs)]
1847#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1848pub enum Grib2Table4_100 {
1849    Analysis = 0,
1850    Forecast = 1,
1851    Reforecast = 2,
1852    Reanalysis = 3,
1853    ClimateProjection = 4,
1854    GriddedObservations = 5,
1855    Missing = 255,
1856}
1857impl From<u8> for Grib2Table4_100 {
1858    fn from(val: u8) -> Self {
1859        match val {
1860            0 => Self::Analysis,
1861            1 => Self::Forecast,
1862            2 => Self::Reforecast,
1863            3 => Self::Reanalysis,
1864            4 => Self::ClimateProjection,
1865            5 => Self::GriddedObservations,
1866            _ => Self::Missing,
1867        }
1868    }
1869}
1870impl core::fmt::Display for Grib2Table4_100 {
1871    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1872        let desc = match self {
1873            Self::Analysis => "Analysis",
1874            Self::Forecast => "Forecast",
1875            Self::Reforecast => "Reforecast (Hindcast)",
1876            Self::Reanalysis => "Reanalysis",
1877            Self::ClimateProjection => "Climate Projection",
1878            Self::GriddedObservations => "Gridded observations",
1879            Self::Missing => "Missing",
1880        };
1881        f.write_str(desc)
1882    }
1883}
1884
1885/// # GRIB2 - CODE TABLE 4.101 - TYPE OF RELATIONSHIP TO REFERENCE DATASET
1886///
1887/// **Details**:
1888/// - **Revised**: 07/12/2024
1889///
1890/// **Reserved Ranges**:
1891/// - `4-19`: Reserved
1892/// - `24-191`: Reserved
1893/// - `192-254`: Reserved for Local Use
1894///
1895/// **Special Value**:
1896/// - `255`: Missing
1897///
1898/// ## Links
1899/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-101.shtml)
1900///
1901/// ## Notes
1902/// 1. No additional parameter is needed for entries `0` and `1` (NA=0).
1903/// 2. Entry `2` (Significance) requires a confidence interval (NA=1).
1904/// 3. Entry `20` (EFI) is defined in [https://doi.org/10.1256/qj.02.152](https://doi.org/10.1256/qj.02.152). No additional parameter is needed.
1905/// 4. Entry `21` (SOT) requires lower and upper quantiles to be defined (NA=2).
1906/// 5. Entry `22` (Anomaly of probabilities) applies to templates `4.112` and `4.123`.
1907/// 6. Entry `23` (Standardized Drought Index) follows definitions from the WMO Handbook on Drought Indicators and Indices.
1908#[repr(u8)]
1909#[allow(missing_docs)]
1910#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1911pub enum Grib2Table4_101 {
1912    Anomaly = 0,
1913    StandardizedAnomaly = 1,
1914    Significance = 2,
1915    Climatology = 3,
1916    ExtremeForecastIndex = 20,
1917    ShiftOfTails = 21,
1918    AnomalyOfProbabilities = 22,
1919    StandardizedDroughtIndex = 23,
1920    Missing = 255,
1921}
1922impl From<u8> for Grib2Table4_101 {
1923    fn from(val: u8) -> Self {
1924        match val {
1925            0 => Self::Anomaly,
1926            1 => Self::StandardizedAnomaly,
1927            2 => Self::Significance,
1928            3 => Self::Climatology,
1929            20 => Self::ExtremeForecastIndex,
1930            21 => Self::ShiftOfTails,
1931            22 => Self::AnomalyOfProbabilities,
1932            23 => Self::StandardizedDroughtIndex,
1933            _ => Self::Missing,
1934        }
1935    }
1936}
1937impl core::fmt::Display for Grib2Table4_101 {
1938    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1939        let desc = match self {
1940            Self::Anomaly => "Anomaly",
1941            Self::StandardizedAnomaly => "Standardized Anomaly",
1942            Self::Significance => "Significance (Wilcoxon-Mann-Whitney)",
1943            Self::Climatology => "Climatology",
1944            Self::ExtremeForecastIndex => "Extreme Forecast Index (EFI)",
1945            Self::ShiftOfTails => "Shift of Tails (SOT)",
1946            Self::AnomalyOfProbabilities => "Anomaly of probabilities",
1947            Self::StandardizedDroughtIndex => "Standardized Drought Index",
1948            Self::Missing => "Missing",
1949        };
1950        f.write_str(desc)
1951    }
1952}
1953
1954/// # GRIB2 - CODE TABLE 4.102 - STATISTICAL PROCESSING OF REFERENCE PERIOD
1955///
1956/// **Details**:
1957/// - **Revised**: 07/12/2024
1958///
1959/// **Reserved Ranges**:
1960/// - `5-19`: Reserved
1961/// - `32-191`: Reserved
1962/// - `192-254`: Reserved for Local Use
1963///
1964/// **Special Value**:
1965/// - `255`: Missing
1966///
1967/// ## Links
1968/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-102.shtml)
1969///
1970/// ## Notes
1971/// None.
1972#[repr(u8)]
1973#[allow(missing_docs)]
1974#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1975pub enum Grib2Table4_102 {
1976    Average = 0,
1977    Accumulation = 1,
1978    Maximum = 2,
1979    Minimum = 3,
1980    Median = 4,
1981    ModelClimate = 20,
1982    IndexBasedOnNormalDistribution = 21,
1983    IndexBasedOnLogNormalDistribution = 22,
1984    IndexBasedOnGeneralisedLogNormalDistribution = 23,
1985    IndexBasedOnGammaDistribution = 24,
1986    IndexBasedOnLogisticDistribution = 25,
1987    IndexBasedOnLogLogisticDistribution = 26,
1988    IndexBasedOnGeneralisedLogisticDistribution = 27,
1989    IndexBasedOnWeibullDistribution = 28,
1990    IndexBasedOnGeneralisedExtremeValueDistribution = 29,
1991    IndexBasedOnPearsonIIIDistribution = 30,
1992    IndexBasedOnEmpiricalDistribution = 31,
1993    Missing = 255,
1994}
1995impl From<u8> for Grib2Table4_102 {
1996    fn from(val: u8) -> Self {
1997        match val {
1998            0 => Self::Average,
1999            1 => Self::Accumulation,
2000            2 => Self::Maximum,
2001            3 => Self::Minimum,
2002            4 => Self::Median,
2003            20 => Self::ModelClimate,
2004            21 => Self::IndexBasedOnNormalDistribution,
2005            22 => Self::IndexBasedOnLogNormalDistribution,
2006            23 => Self::IndexBasedOnGeneralisedLogNormalDistribution,
2007            24 => Self::IndexBasedOnGammaDistribution,
2008            25 => Self::IndexBasedOnLogisticDistribution,
2009            26 => Self::IndexBasedOnLogLogisticDistribution,
2010            27 => Self::IndexBasedOnGeneralisedLogisticDistribution,
2011            28 => Self::IndexBasedOnWeibullDistribution,
2012            29 => Self::IndexBasedOnGeneralisedExtremeValueDistribution,
2013            30 => Self::IndexBasedOnPearsonIIIDistribution,
2014            31 => Self::IndexBasedOnEmpiricalDistribution,
2015            _ => Self::Missing,
2016        }
2017    }
2018}
2019impl core::fmt::Display for Grib2Table4_102 {
2020    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2021        let desc = match self {
2022            Self::Average => "Average",
2023            Self::Accumulation => "Accumulation",
2024            Self::Maximum => "Maximum",
2025            Self::Minimum => "Minimum",
2026            Self::Median => "Median",
2027            Self::ModelClimate => "Model Climate",
2028            Self::IndexBasedOnNormalDistribution => "Index based on normal distribution",
2029            Self::IndexBasedOnLogNormalDistribution => "Index based on log-normal distribution",
2030            Self::IndexBasedOnGeneralisedLogNormalDistribution => {
2031                "Index based on generalised log-normal distribution"
2032            }
2033            Self::IndexBasedOnGammaDistribution => "Index based on gamma distribution",
2034            Self::IndexBasedOnLogisticDistribution => "Index based on logistic distribution",
2035            Self::IndexBasedOnLogLogisticDistribution => "Index based on log-logistic distribution",
2036            Self::IndexBasedOnGeneralisedLogisticDistribution => {
2037                "Index based on generalised logistic distribution"
2038            }
2039            Self::IndexBasedOnWeibullDistribution => "Index based on Weibull distribution",
2040            Self::IndexBasedOnGeneralisedExtremeValueDistribution => {
2041                "Index based on generalised extreme value distribution"
2042            }
2043            Self::IndexBasedOnPearsonIIIDistribution => "Index based on Pearson III distribution",
2044            Self::IndexBasedOnEmpiricalDistribution => "Index based on empirical distribution",
2045            Self::Missing => "Missing",
2046        };
2047        f.write_str(desc)
2048    }
2049}
2050
2051/// # GRIB2 - CODE TABLE 4.103 - SPATIAL VICINITY TYPE
2052///
2053/// **Details**:
2054/// - **Created**: 07/12/2024
2055///
2056/// **Reserved Ranges**:
2057/// - `5-191`: Reserved
2058/// - `192-254`: Reserved for Local Use
2059///
2060/// **Special Value**:
2061/// - `255`: Missing
2062///
2063/// ## Links
2064/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-103.shtml)
2065///
2066/// ## Notes
2067/// 1. The following additional arguments must be specified:
2068///    - **Circle**: 1 argument for the radius in meters.
2069///    - **Rectangle**: 2 arguments for length: 1. west-east and 2. south-north, in meters.
2070///    - **Square**: 1 argument for the length of equal-length sides in meters.
2071///    - **Wedge**: 3 arguments: 1. radius in meters, 2. start angle, and 3. end angle in degrees.
2072///      Angles are measured counter-clockwise from 0° along the positive west-east axis.
2073///    - **Span of grid cells**: 2 arguments for grid cells: 1. west-east span `i +/- x`
2074///      and 2. south-north span `j +/- y`.
2075#[repr(u8)]
2076#[allow(missing_docs)]
2077#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2078pub enum Grib2Table4_103 {
2079    Circle = 0,
2080    Rectangle = 1,
2081    Square = 2,
2082    Wedge = 3,
2083    SpanOfGridBoxesCenteredAroundGridBoxIJ = 4,
2084    Missing = 255,
2085}
2086impl From<u8> for Grib2Table4_103 {
2087    fn from(val: u8) -> Self {
2088        match val {
2089            0 => Self::Circle,
2090            1 => Self::Rectangle,
2091            2 => Self::Square,
2092            3 => Self::Wedge,
2093            4 => Self::SpanOfGridBoxesCenteredAroundGridBoxIJ,
2094            _ => Self::Missing,
2095        }
2096    }
2097}
2098impl core::fmt::Display for Grib2Table4_103 {
2099    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2100        let desc = match self {
2101            Self::Circle => "Circle [m]",
2102            Self::Rectangle => "Rectangle [m, m]",
2103            Self::Square => "Square [m]",
2104            Self::Wedge => "Wedge [m, degree, degree]",
2105            Self::SpanOfGridBoxesCenteredAroundGridBoxIJ => {
2106                "Span of grid boxes centered around grid box i,j [x, y]"
2107            }
2108            Self::Missing => "Missing",
2109        };
2110        f.write_str(desc)
2111    }
2112}
2113
2114/// # GRIB2 - CODE TABLE 4.104 - SPATIAL AND TEMPORAL VICINITY PROCESSING
2115///
2116/// **Details**:
2117/// - **Created**: 07/12/2024
2118///
2119/// **Reserved Ranges**:
2120/// - `1`: Reserved
2121/// - `5`: Reserved
2122/// - `7-10`: Reserved
2123/// - `12-189`: Reserved
2124/// - `192-254`: Reserved for Local Use
2125///
2126/// **Special Value**:
2127/// - `255`: Missing
2128///
2129/// ## Links
2130/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-104.shtml)
2131///
2132/// ## Notes
2133/// 1. The option **Quantile** (Code 190) requires two additional arguments:
2134///    - The total number of quantiles.
2135///    - The quantile value.
2136#[repr(u8)]
2137#[allow(missing_docs)]
2138#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2139pub enum Grib2Table4_104 {
2140    Average = 0,
2141    Reserved1 = 1,
2142    Maximum = 2,
2143    Minimum = 3,
2144    Range = 4,
2145    Reserved5 = 5,
2146    StandardDeviation = 6,
2147    Sum = 11,
2148    Quantile = 190,
2149    Categorical = 191,
2150    Missing = 255,
2151}
2152impl From<u8> for Grib2Table4_104 {
2153    fn from(val: u8) -> Self {
2154        match val {
2155            0 => Self::Average,
2156            1 => Self::Reserved1,
2157            2 => Self::Maximum,
2158            3 => Self::Minimum,
2159            4 => Self::Range,
2160            5 => Self::Reserved5,
2161            6 => Self::StandardDeviation,
2162            11 => Self::Sum,
2163            190 => Self::Quantile,
2164            191 => Self::Categorical,
2165            _ => Self::Missing,
2166        }
2167    }
2168}
2169impl core::fmt::Display for Grib2Table4_104 {
2170    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2171        let desc = match self {
2172            Self::Average => "Average",
2173            Self::Reserved1 => "Reserved",
2174            Self::Maximum => "Maximum",
2175            Self::Minimum => "Minimum",
2176            Self::Range => "Range",
2177            Self::Reserved5 => "Reserved",
2178            Self::StandardDeviation => "Standard deviation",
2179            Self::Sum => "Sum",
2180            Self::Quantile => "Quantile",
2181            Self::Categorical => "Categorical (boolean)",
2182            Self::Missing => "Missing",
2183        };
2184        f.write_str(desc)
2185    }
2186}
2187
2188/// # GRIB2 - CODE TABLE 4.105 - SPATIAL AND TEMPORAL VICINITY MISSING DATA
2189///
2190/// **Details**:
2191/// - **Created**: 07/12/2024
2192///
2193/// **Reserved Ranges**:
2194/// - `2-191`: Reserved
2195/// - `192-254`: Reserved for Local Use
2196///
2197/// **Special Value**:
2198/// - `255`: Missing
2199///
2200/// ## Links
2201/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-105.shtml)
2202///
2203/// ## Notes
2204/// None.
2205#[repr(u8)]
2206#[allow(missing_docs)]
2207#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2208pub enum Grib2Table4_105 {
2209    IgnoreMissingData = 0,
2210    NoData = 1,
2211    Missing = 255,
2212}
2213impl From<u8> for Grib2Table4_105 {
2214    fn from(val: u8) -> Self {
2215        match val {
2216            0 => Self::IgnoreMissingData,
2217            1 => Self::NoData,
2218            _ => Self::Missing,
2219        }
2220    }
2221}
2222impl core::fmt::Display for Grib2Table4_105 {
2223    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2224        let desc = match self {
2225            Self::IgnoreMissingData => "Ignore missing data",
2226            Self::NoData => "No data",
2227            Self::Missing => "Missing",
2228        };
2229        f.write_str(desc)
2230    }
2231}
2232
2233/// # GRIB2 - CODE TABLE 4.201 - PRECIPITATION TYPE
2234///
2235/// **Details**:
2236/// - **Revised**: 05/29/2019
2237///
2238/// **Reserved Ranges**:
2239/// - `13-191`: Reserved
2240/// - `192-254`: Reserved for Local Use
2241///
2242/// **Special Value**:
2243/// - `255`: Missing
2244///
2245/// ## Links
2246/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-201.shtml)
2247///
2248/// ## Notes
2249/// None.
2250#[repr(u8)]
2251#[allow(missing_docs)]
2252#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2253pub enum Grib2Table4_201 {
2254    Reserved = 0,
2255    Rain = 1,
2256    Thunderstorm = 2,
2257    FreezingRain = 3,
2258    MixedIce = 4,
2259    Snow = 5,
2260    WetSnow = 6,
2261    MixtureOfRainAndSnow = 7,
2262    IcePellets = 8,
2263    Graupel = 9,
2264    Hail = 10,
2265    Drizzle = 11,
2266    FreezingDrizzle = 12,
2267    Missing = 255,
2268}
2269impl From<u8> for Grib2Table4_201 {
2270    fn from(val: u8) -> Self {
2271        match val {
2272            0 => Self::Reserved,
2273            1 => Self::Rain,
2274            2 => Self::Thunderstorm,
2275            3 => Self::FreezingRain,
2276            4 => Self::MixedIce,
2277            5 => Self::Snow,
2278            6 => Self::WetSnow,
2279            7 => Self::MixtureOfRainAndSnow,
2280            8 => Self::IcePellets,
2281            9 => Self::Graupel,
2282            10 => Self::Hail,
2283            11 => Self::Drizzle,
2284            12 => Self::FreezingDrizzle,
2285            _ => Self::Missing,
2286        }
2287    }
2288}
2289impl core::fmt::Display for Grib2Table4_201 {
2290    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2291        let desc = match self {
2292            Self::Reserved => "Reserved",
2293            Self::Rain => "Rain",
2294            Self::Thunderstorm => "Thunderstorm",
2295            Self::FreezingRain => "Freezing Rain",
2296            Self::MixedIce => "Mixed/Ice",
2297            Self::Snow => "Snow",
2298            Self::WetSnow => "Wet Snow",
2299            Self::MixtureOfRainAndSnow => "Mixture of Rain and Snow",
2300            Self::IcePellets => "Ice Pellets",
2301            Self::Graupel => "Graupel",
2302            Self::Hail => "Hail",
2303            Self::Drizzle => "Drizzle",
2304            Self::FreezingDrizzle => "Freezing Drizzle",
2305            Self::Missing => "Missing",
2306        };
2307        f.write_str(desc)
2308    }
2309}
2310
2311/// # GRIB2 - CODE TABLE 4.202 - PRECIPITABLE WATER CATEGORY
2312///
2313/// **Details**:
2314/// - **Created**: 05/16/2005
2315///
2316/// **Reserved Ranges**:
2317/// - `0-191`: Reserved
2318/// - `192-254`: Reserved for Local Use
2319///
2320/// **Special Value**:
2321/// - `255`: Missing
2322///
2323/// ## Links
2324/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-202.shtml)
2325///
2326/// ## Notes
2327/// None.
2328#[repr(u8)]
2329#[allow(missing_docs)]
2330#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2331pub enum Grib2Table4_202 {
2332    Missing = 255,
2333}
2334impl From<u8> for Grib2Table4_202 {
2335    fn from(_: u8) -> Self {
2336        Self::Missing
2337    }
2338}
2339impl core::fmt::Display for Grib2Table4_202 {
2340    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2341        let desc = match self {
2342            Self::Missing => "Missing",
2343        };
2344        f.write_str(desc)
2345    }
2346}
2347
2348/// # GRIB2 - CODE TABLE 4.203 - CLOUD TYPE
2349///
2350/// **Details**:
2351/// - **Created**: 05/16/2005
2352///
2353/// **Reserved Ranges**:
2354/// - `21-190`: Reserved
2355/// - `192-254`: Reserved for Local Use
2356///
2357/// **Special Value**:
2358/// - `191`: Unknown
2359/// - `255`: Missing
2360///
2361/// ## Links
2362/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-203.shtml)
2363///
2364/// ## Notes
2365/// 1. Code figures `11-20` indicate all four layers were used and ground-based fog is below the lowest layer.
2366#[repr(u8)]
2367#[allow(missing_docs)]
2368#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2369pub enum Grib2Table4_203 {
2370    Clear = 0,
2371    Cumulonimbus = 1,
2372    Stratus = 2,
2373    Stratocumulus = 3,
2374    Cumulus = 4,
2375    Altostratus = 5,
2376    Nimbostratus = 6,
2377    Altocumulus = 7,
2378    Cirrostratus = 8,
2379    Cirrocumulus = 9,
2380    Cirrus = 10,
2381    CumulonimbusGroundBasedFog = 11,
2382    StratusGroundBasedFog = 12,
2383    StratocumulusGroundBasedFog = 13,
2384    CumulusGroundBasedFog = 14,
2385    AltostratusGroundBasedFog = 15,
2386    NimbostratusGroundBasedFog = 16,
2387    AltocumulusGroundBasedFog = 17,
2388    CirrostratusGroundBasedFog = 18,
2389    CirrocumulusGroundBasedFog = 19,
2390    CirrusGroundBasedFog = 20,
2391    Unknown = 191,
2392    Missing = 255,
2393}
2394impl From<u8> for Grib2Table4_203 {
2395    fn from(val: u8) -> Self {
2396        match val {
2397            0 => Self::Clear,
2398            1 => Self::Cumulonimbus,
2399            2 => Self::Stratus,
2400            3 => Self::Stratocumulus,
2401            4 => Self::Cumulus,
2402            5 => Self::Altostratus,
2403            6 => Self::Nimbostratus,
2404            7 => Self::Altocumulus,
2405            8 => Self::Cirrostratus,
2406            9 => Self::Cirrocumulus,
2407            10 => Self::Cirrus,
2408            11 => Self::CumulonimbusGroundBasedFog,
2409            12 => Self::StratusGroundBasedFog,
2410            13 => Self::StratocumulusGroundBasedFog,
2411            14 => Self::CumulusGroundBasedFog,
2412            15 => Self::AltostratusGroundBasedFog,
2413            16 => Self::NimbostratusGroundBasedFog,
2414            17 => Self::AltocumulusGroundBasedFog,
2415            18 => Self::CirrostratusGroundBasedFog,
2416            19 => Self::CirrocumulusGroundBasedFog,
2417            20 => Self::CirrusGroundBasedFog,
2418            191 => Self::Unknown,
2419            _ => Self::Missing,
2420        }
2421    }
2422}
2423impl core::fmt::Display for Grib2Table4_203 {
2424    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2425        let desc = match self {
2426            Self::Clear => "Clear",
2427            Self::Cumulonimbus => "Cumulonimbus",
2428            Self::Stratus => "Stratus",
2429            Self::Stratocumulus => "Stratocumulus",
2430            Self::Cumulus => "Cumulus",
2431            Self::Altostratus => "Altostratus",
2432            Self::Nimbostratus => "Nimbostratus",
2433            Self::Altocumulus => "Altocumulus",
2434            Self::Cirrostratus => "Cirrostratus",
2435            Self::Cirrocumulus => "Cirrorcumulus",
2436            Self::Cirrus => "Cirrus",
2437            Self::CumulonimbusGroundBasedFog => {
2438                "Cumulonimbus - ground-based fog beneath the lowest layer"
2439            }
2440            Self::StratusGroundBasedFog => "Stratus - ground-based fog beneath the lowest layer",
2441            Self::StratocumulusGroundBasedFog => {
2442                "Stratocumulus - ground-based fog beneath the lowest layer"
2443            }
2444            Self::CumulusGroundBasedFog => "Cumulus - ground-based fog beneath the lowest layer",
2445            Self::AltostratusGroundBasedFog => {
2446                "Altostratus - ground-based fog beneath the lowest layer"
2447            }
2448            Self::NimbostratusGroundBasedFog => {
2449                "Nimbostratus - ground-based fog beneath the lowest layer"
2450            }
2451            Self::AltocumulusGroundBasedFog => {
2452                "Altocumulus - ground-based fog beneath the lowest layer"
2453            }
2454            Self::CirrostratusGroundBasedFog => {
2455                "Cirrostratus - ground-based fog beneath the lowest layer"
2456            }
2457            Self::CirrocumulusGroundBasedFog => {
2458                "Cirrorcumulus - ground-based fog beneath the lowest layer"
2459            }
2460            Self::CirrusGroundBasedFog => "Cirrus - ground-based fog beneath the lowest layer",
2461            Self::Unknown => "Unknown",
2462            Self::Missing => "Missing",
2463        };
2464        f.write_str(desc)
2465    }
2466}
2467
2468/// # GRIB2 - CODE TABLE 4.204 - THUNDERSTORM COVERAGE
2469///
2470/// **Details**:
2471/// - **Created**: 05/16/2005
2472///
2473/// **Reserved Ranges**:
2474/// - `5-191`: Reserved
2475/// - `192-254`: Reserved for Local Use
2476///
2477/// **Special Value**:
2478/// - `255`: Missing
2479///
2480/// ## Links
2481/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-204.shtml)
2482///
2483/// ## Notes
2484/// None.
2485#[repr(u8)]
2486#[allow(missing_docs)]
2487#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2488pub enum Grib2Table4_204 {
2489    None = 0,
2490    Isolated = 1,
2491    Few = 2,
2492    Scattered = 3,
2493    Numerous = 4,
2494    Missing = 255,
2495}
2496impl From<u8> for Grib2Table4_204 {
2497    fn from(val: u8) -> Self {
2498        match val {
2499            0 => Self::None,
2500            1 => Self::Isolated,
2501            2 => Self::Few,
2502            3 => Self::Scattered,
2503            4 => Self::Numerous,
2504            _ => Self::Missing,
2505        }
2506    }
2507}
2508impl core::fmt::Display for Grib2Table4_204 {
2509    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2510        let desc = match self {
2511            Self::None => "None",
2512            Self::Isolated => "Isolated (1-2%)",
2513            Self::Few => "Few (3-5%)",
2514            Self::Scattered => "Scattered (16-45%)",
2515            Self::Numerous => "Numerous (>45%)",
2516            Self::Missing => "Missing",
2517        };
2518        f.write_str(desc)
2519    }
2520}
2521
2522/// # GRIB2 - CODE TABLE 4.205 - PRESENCE OF AEROSOL
2523///
2524/// **Details**:
2525/// - **Created**: 05/16/2005
2526///
2527/// **Reserved Ranges**:
2528/// - `2-191`: Reserved
2529/// - `192-254`: Reserved for Local Use
2530///
2531/// **Special Value**:
2532/// - `255`: Missing
2533///
2534/// ## Links
2535/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-205.shtml)
2536///
2537/// ## Notes
2538/// None.
2539#[repr(u8)]
2540#[allow(missing_docs)]
2541#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2542pub enum Grib2Table4_205 {
2543    AerosolNotPresent = 0,
2544    AerosolPresent = 1,
2545    Missing = 255,
2546}
2547impl From<u8> for Grib2Table4_205 {
2548    fn from(val: u8) -> Self {
2549        match val {
2550            0 => Self::AerosolNotPresent,
2551            1 => Self::AerosolPresent,
2552            _ => Self::Missing,
2553        }
2554    }
2555}
2556impl core::fmt::Display for Grib2Table4_205 {
2557    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2558        let desc = match self {
2559            Self::AerosolNotPresent => "Aerosol not present",
2560            Self::AerosolPresent => "Aerosol present",
2561            Self::Missing => "Missing",
2562        };
2563        f.write_str(desc)
2564    }
2565}
2566
2567/// # GRIB2 - CODE TABLE 4.206 - VOLCANIC ASH
2568///
2569/// **Details**:
2570/// - **Created**: 05/16/2005
2571///
2572/// **Reserved Ranges**:
2573/// - `2-191`: Reserved
2574/// - `192-254`: Reserved for Local Use
2575///
2576/// **Special Value**:
2577/// - `255`: Missing
2578///
2579/// ## Links
2580/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-206.shtml)
2581///
2582/// ## Notes
2583/// None.
2584#[repr(u8)]
2585#[allow(missing_docs)]
2586#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2587pub enum Grib2Table4_206 {
2588    NotPresent = 0,
2589    Present = 1,
2590    Missing = 255,
2591}
2592impl From<u8> for Grib2Table4_206 {
2593    fn from(val: u8) -> Self {
2594        match val {
2595            0 => Self::NotPresent,
2596            1 => Self::Present,
2597            _ => Self::Missing,
2598        }
2599    }
2600}
2601impl core::fmt::Display for Grib2Table4_206 {
2602    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2603        let desc = match self {
2604            Self::NotPresent => "Not Present",
2605            Self::Present => "Present",
2606            Self::Missing => "Missing",
2607        };
2608        f.write_str(desc)
2609    }
2610}
2611
2612/// # GRIB2 - CODE TABLE 4.207 - ICING
2613///
2614/// **Details**:
2615/// - **Revised**: 04/22/2009
2616///
2617/// **Reserved Ranges**:
2618/// - `6-191`: Reserved
2619/// - `192-254`: Reserved for Local Use
2620///
2621/// **Special Value**:
2622/// - `255`: Missing
2623///
2624/// ## Links
2625/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-207.shtml)
2626///
2627/// ## Notes
2628/// None.
2629#[repr(u8)]
2630#[allow(missing_docs)]
2631#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2632pub enum Grib2Table4_207 {
2633    None = 0,
2634    Light = 1,
2635    Moderate = 2,
2636    Severe = 3,
2637    Trace = 4,
2638    Heavy = 5,
2639    Missing = 255,
2640}
2641impl From<u8> for Grib2Table4_207 {
2642    fn from(val: u8) -> Self {
2643        match val {
2644            0 => Self::None,
2645            1 => Self::Light,
2646            2 => Self::Moderate,
2647            3 => Self::Severe,
2648            4 => Self::Trace,
2649            5 => Self::Heavy,
2650            _ => Self::Missing,
2651        }
2652    }
2653}
2654impl core::fmt::Display for Grib2Table4_207 {
2655    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2656        let desc = match self {
2657            Self::None => "None",
2658            Self::Light => "Light",
2659            Self::Moderate => "Moderate",
2660            Self::Severe => "Severe",
2661            Self::Trace => "Trace",
2662            Self::Heavy => "Data missing",
2663            Self::Missing => "Missing",
2664        };
2665        f.write_str(desc)
2666    }
2667}
2668
2669/// # GRIB2 - CODE TABLE 4.208 - TURBULENCE
2670///
2671/// **Details**:
2672/// - **Created**: 05/16/2005
2673///
2674/// **Reserved Ranges**:
2675/// - `5-191`: Reserved
2676/// - `192-254`: Reserved for Local Use
2677///
2678/// **Special Value**:
2679/// - `255`: Missing
2680///
2681/// ## Links
2682/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-208.shtml)
2683///
2684/// ## Notes
2685/// None.
2686#[repr(u8)]
2687#[allow(missing_docs)]
2688#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2689pub enum Grib2Table4_208 {
2690    None = 0,
2691    Light = 1,
2692    Moderate = 2,
2693    Severe = 3,
2694    Extreme = 4,
2695    Missing = 255,
2696}
2697impl From<u8> for Grib2Table4_208 {
2698    fn from(val: u8) -> Self {
2699        match val {
2700            0 => Self::None,
2701            1 => Self::Light,
2702            2 => Self::Moderate,
2703            3 => Self::Severe,
2704            4 => Self::Extreme,
2705            _ => Self::Missing,
2706        }
2707    }
2708}
2709impl core::fmt::Display for Grib2Table4_208 {
2710    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2711        let desc = match self {
2712            Self::None => "None",
2713            Self::Light => "Light",
2714            Self::Moderate => "Moderate",
2715            Self::Severe => "Severe",
2716            Self::Extreme => "Extreme",
2717            Self::Missing => "Missing",
2718        };
2719        f.write_str(desc)
2720    }
2721}
2722
2723/// # GRIB2 - CODE TABLE 4.209 - PLANETARY BOUNDARY-LAYER REGIME
2724///
2725/// **Details**:
2726/// - **Created**: 05/16/2005
2727///
2728/// **Reserved Ranges**:
2729/// - `5-191`: Reserved
2730/// - `192-254`: Reserved for Local Use
2731///
2732/// **Special Value**:
2733/// - `255`: Missing
2734///
2735/// ## Links
2736/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-209.shtml)
2737///
2738/// ## Notes
2739/// None.
2740#[repr(u8)]
2741#[allow(missing_docs)]
2742#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2743pub enum Grib2Table4_209 {
2744    Reserved = 0,
2745    Stable = 1,
2746    MechanicallyDrivenTurbulence = 2,
2747    ForceConvection = 3,
2748    FreeConvection = 4,
2749    Missing = 255,
2750}
2751impl From<u8> for Grib2Table4_209 {
2752    fn from(val: u8) -> Self {
2753        match val {
2754            0 => Self::Reserved,
2755            1 => Self::Stable,
2756            2 => Self::MechanicallyDrivenTurbulence,
2757            3 => Self::ForceConvection,
2758            4 => Self::FreeConvection,
2759            _ => Self::Missing,
2760        }
2761    }
2762}
2763impl core::fmt::Display for Grib2Table4_209 {
2764    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2765        let desc = match self {
2766            Self::Reserved => "Reserved",
2767            Self::Stable => "Stable",
2768            Self::MechanicallyDrivenTurbulence => "Mechanically-Driven Turbulence",
2769            Self::ForceConvection => "Force Convection",
2770            Self::FreeConvection => "Free Convection",
2771            Self::Missing => "Missing",
2772        };
2773        f.write_str(desc)
2774    }
2775}
2776
2777/// # GRIB2 - CODE TABLE 4.210 - CONTRAIL INTENSITY
2778///
2779/// **Details**:
2780/// - **Created**: 05/16/2005
2781///
2782/// **Reserved Ranges**:
2783/// - `2-191`: Reserved
2784/// - `192-254`: Reserved for Local Use
2785///
2786/// **Special Value**:
2787/// - `255`: Missing
2788///
2789/// ## Links
2790/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-210.shtml)
2791///
2792/// ## Notes
2793/// None.
2794#[repr(u8)]
2795#[allow(missing_docs)]
2796#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2797pub enum Grib2Table4_210 {
2798    ContrailNotPresent = 0,
2799    ContrailPresent = 1,
2800    Missing = 255,
2801}
2802impl From<u8> for Grib2Table4_210 {
2803    fn from(val: u8) -> Self {
2804        match val {
2805            0 => Self::ContrailNotPresent,
2806            1 => Self::ContrailPresent,
2807            _ => Self::Missing,
2808        }
2809    }
2810}
2811impl core::fmt::Display for Grib2Table4_210 {
2812    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2813        let desc = match self {
2814            Self::ContrailNotPresent => "Contrail Not Present",
2815            Self::ContrailPresent => "Contrail Present",
2816            Self::Missing => "Missing",
2817        };
2818        f.write_str(desc)
2819    }
2820}
2821
2822/// # GRIB2 - CODE TABLE 4.211 - CONTRAIL ENGINE TYPE
2823///
2824/// **Details**:
2825/// - **Created**: 05/16/2005
2826///
2827/// **Reserved Ranges**:
2828/// - `3-191`: Reserved
2829/// - `192-254`: Reserved for Local Use
2830///
2831/// **Special Value**:
2832/// - `255`: Missing
2833///
2834/// ## Links
2835/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-211.shtml)
2836///
2837/// ## Notes
2838/// None.
2839#[repr(u8)]
2840#[allow(missing_docs)]
2841#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2842pub enum Grib2Table4_211 {
2843    LowBypass = 0,
2844    HighBypass = 1,
2845    NonBypass = 2,
2846    Missing = 255,
2847}
2848impl From<u8> for Grib2Table4_211 {
2849    fn from(val: u8) -> Self {
2850        match val {
2851            0 => Self::LowBypass,
2852            1 => Self::HighBypass,
2853            2 => Self::NonBypass,
2854            _ => Self::Missing,
2855        }
2856    }
2857}
2858impl core::fmt::Display for Grib2Table4_211 {
2859    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2860        let desc = match self {
2861            Self::LowBypass => "Low Bypass",
2862            Self::HighBypass => "High Bypass",
2863            Self::NonBypass => "Non-Bypass",
2864            Self::Missing => "Missing",
2865        };
2866        f.write_str(desc)
2867    }
2868}
2869
2870/// # GRIB2 - CODE TABLE 4.212 - LAND USE
2871///
2872/// **Details**:
2873/// - **Created**: 05/16/2005
2874///
2875/// **Reserved Ranges**:
2876/// - `14-191`: Reserved
2877/// - `192-254`: Reserved for Local Use
2878///
2879/// **Special Value**:
2880/// - `255`: Missing
2881///
2882/// ## Links
2883/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-212.shtml)
2884///
2885/// ## Notes
2886/// None.
2887#[repr(u8)]
2888#[allow(missing_docs)]
2889#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2890pub enum Grib2Table4_212 {
2891    Reserved = 0,
2892    UrbanLand = 1,
2893    Agricultural = 2,
2894    RangeLand = 3,
2895    DeciduousForest = 4,
2896    ConiferousForest = 5,
2897    ForestWetland = 6,
2898    Water = 7,
2899    Wetlands = 8,
2900    Desert = 9,
2901    Tundra = 10,
2902    Ice = 11,
2903    TropicalForest = 12,
2904    Savannah = 13,
2905    Missing = 255,
2906}
2907impl From<u8> for Grib2Table4_212 {
2908    fn from(val: u8) -> Self {
2909        match val {
2910            0 => Self::Reserved,
2911            1 => Self::UrbanLand,
2912            2 => Self::Agricultural,
2913            3 => Self::RangeLand,
2914            4 => Self::DeciduousForest,
2915            5 => Self::ConiferousForest,
2916            6 => Self::ForestWetland,
2917            7 => Self::Water,
2918            8 => Self::Wetlands,
2919            9 => Self::Desert,
2920            10 => Self::Tundra,
2921            11 => Self::Ice,
2922            12 => Self::TropicalForest,
2923            13 => Self::Savannah,
2924            _ => Self::Missing,
2925        }
2926    }
2927}
2928impl core::fmt::Display for Grib2Table4_212 {
2929    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2930        let desc = match self {
2931            Self::Reserved => "Reserved",
2932            Self::UrbanLand => "Urban Land",
2933            Self::Agricultural => "Agricultural",
2934            Self::RangeLand => "Range Land",
2935            Self::DeciduousForest => "Deciduous Forest",
2936            Self::ConiferousForest => "Coniferous Forest",
2937            Self::ForestWetland => "Forest/Wetland",
2938            Self::Water => "Water",
2939            Self::Wetlands => "Wetlands",
2940            Self::Desert => "Desert",
2941            Self::Tundra => "Tundra",
2942            Self::Ice => "Ice",
2943            Self::TropicalForest => "Tropical Forest",
2944            Self::Savannah => "Savannah",
2945            Self::Missing => "Missing",
2946        };
2947        f.write_str(desc)
2948    }
2949}
2950
2951/// # GRIB2 - CODE TABLE 4.213 - SOIL TYPE
2952///
2953/// **Details**:
2954/// - **Revised**: 07/16/2013
2955///
2956/// **Reserved Ranges**:
2957/// - `12-191`: Reserved
2958/// - `192-254`: Reserved for Local Use
2959///
2960/// **Special Value**:
2961/// - `255`: Missing
2962///
2963/// ## Links
2964/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-213.shtml)
2965///
2966/// ## Notes
2967/// None.
2968#[repr(u8)]
2969#[allow(missing_docs)]
2970#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2971pub enum Grib2Table4_213 {
2972    Reserved = 0,
2973    Sand = 1,
2974    LoamySand = 2,
2975    SandyLoam = 3,
2976    SiltLoam = 4,
2977    Organic = 5,
2978    SandyClayLoam = 6,
2979    SiltClayLoam = 7,
2980    ClayLoam = 8,
2981    SandyClay = 9,
2982    SiltyClay = 10,
2983    Clay = 11,
2984    Missing = 255,
2985}
2986impl From<u8> for Grib2Table4_213 {
2987    fn from(val: u8) -> Self {
2988        match val {
2989            0 => Self::Reserved,
2990            1 => Self::Sand,
2991            2 => Self::LoamySand,
2992            3 => Self::SandyLoam,
2993            4 => Self::SiltLoam,
2994            5 => Self::Organic,
2995            6 => Self::SandyClayLoam,
2996            7 => Self::SiltClayLoam,
2997            8 => Self::ClayLoam,
2998            9 => Self::SandyClay,
2999            10 => Self::SiltyClay,
3000            11 => Self::Clay,
3001            _ => Self::Missing,
3002        }
3003    }
3004}
3005impl core::fmt::Display for Grib2Table4_213 {
3006    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3007        let desc = match self {
3008            Self::Reserved => "Reserved",
3009            Self::Sand => "Sand",
3010            Self::LoamySand => "Loamy Sand",
3011            Self::SandyLoam => "Sandy Loam",
3012            Self::SiltLoam => "Silt Loam",
3013            Self::Organic => "Organic",
3014            Self::SandyClayLoam => "Sandy Clay Loam",
3015            Self::SiltClayLoam => "Silt Clay Loam",
3016            Self::ClayLoam => "Clay Loam",
3017            Self::SandyClay => "Sandy Clay",
3018            Self::SiltyClay => "Silty Clay",
3019            Self::Clay => "Clay",
3020            Self::Missing => "Missing",
3021        };
3022        f.write_str(desc)
3023    }
3024}
3025
3026/// # GRIB2 - CODE TABLE 4.214 - ENVIRONMENTAL FACTOR QUALIFIER
3027///
3028/// **Details**:
3029/// - **Created**: 10/24/2023
3030///
3031/// **Reserved Ranges**:
3032/// - `6-190`: Reserved
3033/// - `192-254`: Reserved for Local Use
3034///
3035/// **Special Value**:
3036/// - `191`: Unknown
3037/// - `255`: Missing
3038///
3039/// ## Links
3040/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-214.shtml)
3041///
3042/// ## Notes
3043/// None.
3044#[repr(u8)]
3045#[allow(missing_docs)]
3046#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3047pub enum Grib2Table4_214 {
3048    Worst = 0,
3049    VeryPoor = 1,
3050    Poor = 2,
3051    Average = 3,
3052    Good = 4,
3053    Excellent = 5,
3054    Unknown = 191,
3055    Missing = 255,
3056}
3057impl From<u8> for Grib2Table4_214 {
3058    fn from(val: u8) -> Self {
3059        match val {
3060            0 => Self::Worst,
3061            1 => Self::VeryPoor,
3062            2 => Self::Poor,
3063            3 => Self::Average,
3064            4 => Self::Good,
3065            5 => Self::Excellent,
3066            191 => Self::Unknown,
3067            _ => Self::Missing,
3068        }
3069    }
3070}
3071impl core::fmt::Display for Grib2Table4_214 {
3072    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3073        let desc = match self {
3074            Self::Worst => "Worst",
3075            Self::VeryPoor => "Very poor",
3076            Self::Poor => "Poor",
3077            Self::Average => "Average",
3078            Self::Good => "Good",
3079            Self::Excellent => "Excellent",
3080            Self::Unknown => "Unknown",
3081            Self::Missing => "Missing",
3082        };
3083        f.write_str(desc)
3084    }
3085}
3086
3087/// # GRIB2 - CODE TABLE 4.215 - REMOTELY-SENSED SNOW COVERAGE
3088///
3089/// **Details**:
3090/// - **Created**: 05/16/2005
3091///
3092/// **Reserved Ranges**:
3093/// - `0-49`: Reserved
3094/// - `51-99`: Reserved
3095/// - `101-249`: Reserved
3096/// - `192-254`: Reserved for Local Use
3097///
3098/// **Special Value**:
3099/// - `50`: No-Snow/No-Cloud
3100/// - `100`: Clouds
3101/// - `250`: Snow
3102/// - `255`: Missing
3103///
3104/// ## Links
3105/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-215.shtml)
3106///
3107/// ## Notes
3108/// None.
3109#[repr(u8)]
3110#[allow(missing_docs)]
3111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3112pub enum Grib2Table4_215 {
3113    NoSnowNoCloud = 50,
3114    Clouds = 100,
3115    Snow = 250,
3116    Missing = 255,
3117}
3118impl From<u8> for Grib2Table4_215 {
3119    fn from(val: u8) -> Self {
3120        match val {
3121            50 => Self::NoSnowNoCloud,
3122            100 => Self::Clouds,
3123            250 => Self::Snow,
3124            _ => Self::Missing,
3125        }
3126    }
3127}
3128impl core::fmt::Display for Grib2Table4_215 {
3129    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3130        let desc = match self {
3131            Self::NoSnowNoCloud => "No-Snow/No-Cloud",
3132            Self::Clouds => "Clouds",
3133            Self::Snow => "Snow",
3134            Self::Missing => "Missing",
3135        };
3136        f.write_str(desc)
3137    }
3138}
3139
3140/// # GRIB2 - CODE TABLE 4.216 - ELEVATION OF SNOW COVERED TERRAIN
3141///
3142/// **Details**:
3143/// - **Created**: 05/16/2005
3144///
3145/// **Reserved Ranges**:
3146/// - `91-253`: Reserved
3147///
3148/// **Special Values**:
3149/// - `0-90`: Elevation in increments of 100 m
3150/// - `254`: Clouds
3151/// - `255`: Missing
3152///
3153/// ## Links
3154/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-216.shtml)
3155///
3156/// ## Notes
3157/// None.
3158#[repr(u8)]
3159#[allow(missing_docs)]
3160#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3161pub enum Grib2Table4_216 {
3162    Elevation100m = 0, // This represents values 0-90
3163    Clouds = 254,
3164    Missing = 255,
3165}
3166impl From<u8> for Grib2Table4_216 {
3167    fn from(val: u8) -> Self {
3168        match val {
3169            0..=90 => Self::Elevation100m,
3170            254 => Self::Clouds,
3171            _ => Self::Missing,
3172        }
3173    }
3174}
3175impl core::fmt::Display for Grib2Table4_216 {
3176    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3177        let desc = match self {
3178            Self::Elevation100m => "Elevation in increments of 100 m",
3179            Self::Clouds => "Clouds",
3180            Self::Missing => "Missing",
3181        };
3182        f.write_str(desc)
3183    }
3184}
3185
3186/// # GRIB2 - CODE TABLE 4.217 - CLOUD MASK TYPE
3187///
3188/// **Details**:
3189/// - **Created**: 05/16/2005
3190///
3191/// **Reserved Ranges**:
3192/// - `4-191`: Reserved
3193/// - `192-254`: Reserved for Local Use
3194///
3195/// **Special Value**:
3196/// - `255`: Missing
3197///
3198/// ## Links
3199/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-217.shtml)
3200///
3201/// ## Notes
3202/// None.
3203#[repr(u8)]
3204#[allow(missing_docs)]
3205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3206pub enum Grib2Table4_217 {
3207    ClearOverWater = 0,
3208    ClearOverLand = 1,
3209    Cloud = 2,
3210    NoData = 3,
3211    Missing = 255,
3212}
3213impl From<u8> for Grib2Table4_217 {
3214    fn from(val: u8) -> Self {
3215        match val {
3216            0 => Self::ClearOverWater,
3217            1 => Self::ClearOverLand,
3218            2 => Self::Cloud,
3219            3 => Self::NoData,
3220            _ => Self::Missing,
3221        }
3222    }
3223}
3224impl core::fmt::Display for Grib2Table4_217 {
3225    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3226        let desc = match self {
3227            Self::ClearOverWater => "Clear over water",
3228            Self::ClearOverLand => "Clear over land",
3229            Self::Cloud => "Cloud",
3230            Self::NoData => "No data",
3231            Self::Missing => "Missing",
3232        };
3233        f.write_str(desc)
3234    }
3235}
3236
3237/// # GRIB2 - CODE TABLE 4.218 - PIXEL SCENE TYPE
3238///
3239/// **Details**:
3240/// - **Revised**: 05/29/2019
3241///
3242/// **Reserved Ranges**:
3243/// - `25-96`: Reserved
3244/// - `113-191`: Reserved
3245/// - `192-254`: Reserved for Local Use
3246///
3247/// **Special Value**:
3248/// - `255`: Missing
3249///
3250/// ## Links
3251/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-218.shtml)
3252///
3253/// ## Notes
3254/// None.
3255#[repr(u8)]
3256#[allow(missing_docs)]
3257#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3258pub enum Grib2Table4_218 {
3259    NoSceneIdentified = 0,
3260    GreenNeedleLeafedForest = 1,
3261    GreenBroadLeafedForest = 2,
3262    DeciduousNeedleLeafedForest = 3,
3263    DeciduousBroadLeafedForest = 4,
3264    DeciduousMixedForest = 5,
3265    ClosedShrubLand = 6,
3266    OpenShrubLand = 7,
3267    WoodySavannah = 8,
3268    Savannah = 9,
3269    Grassland = 10,
3270    PermanentWetland = 11,
3271    Cropland = 12,
3272    Urban = 13,
3273    VegetationCrops = 14,
3274    PermanentSnowIce = 15,
3275    BarrenDesert = 16,
3276    WaterBodies = 17,
3277    Tundra = 18,
3278    WarmLiquidWaterCloud = 19,
3279    SupercooledLiquidWaterCloud = 20,
3280    MixedPhaseCloud = 21,
3281    OpticallyThinIceCloud = 22,
3282    OpticallyThickIceCloud = 23,
3283    MultiLayerBlackCloud = 24,
3284    SnowIceOnLand = 97,
3285    SnowIceOnWater = 98,
3286    SunGlint = 99,
3287    GeneralCloud = 100,
3288    LowCloudFogStratus = 101,
3289    LowCloudStratocumulus = 102,
3290    LowCloudUnknownType = 103,
3291    MediumCloudNimbostratus = 104,
3292    MediumCloudAltostratus = 105,
3293    MediumCloudUnknownType = 106,
3294    HighCloudCumulus = 107,
3295    HighCloudCirrus = 108,
3296    HighCloudUnknownType = 109,
3297    UnknownCloudType = 110,
3298    SingleLayerWaterCloud = 111,
3299    SingleLayerIceCloud = 112,
3300    Missing = 255,
3301}
3302impl From<u8> for Grib2Table4_218 {
3303    fn from(val: u8) -> Self {
3304        match val {
3305            0 => Self::NoSceneIdentified,
3306            1 => Self::GreenNeedleLeafedForest,
3307            2 => Self::GreenBroadLeafedForest,
3308            3 => Self::DeciduousNeedleLeafedForest,
3309            4 => Self::DeciduousBroadLeafedForest,
3310            5 => Self::DeciduousMixedForest,
3311            6 => Self::ClosedShrubLand,
3312            7 => Self::OpenShrubLand,
3313            8 => Self::WoodySavannah,
3314            9 => Self::Savannah,
3315            10 => Self::Grassland,
3316            11 => Self::PermanentWetland,
3317            12 => Self::Cropland,
3318            13 => Self::Urban,
3319            14 => Self::VegetationCrops,
3320            15 => Self::PermanentSnowIce,
3321            16 => Self::BarrenDesert,
3322            17 => Self::WaterBodies,
3323            18 => Self::Tundra,
3324            19 => Self::WarmLiquidWaterCloud,
3325            20 => Self::SupercooledLiquidWaterCloud,
3326            21 => Self::MixedPhaseCloud,
3327            22 => Self::OpticallyThinIceCloud,
3328            23 => Self::OpticallyThickIceCloud,
3329            24 => Self::MultiLayerBlackCloud,
3330            97 => Self::SnowIceOnLand,
3331            98 => Self::SnowIceOnWater,
3332            99 => Self::SunGlint,
3333            100 => Self::GeneralCloud,
3334            101 => Self::LowCloudFogStratus,
3335            102 => Self::LowCloudStratocumulus,
3336            103 => Self::LowCloudUnknownType,
3337            104 => Self::MediumCloudNimbostratus,
3338            105 => Self::MediumCloudAltostratus,
3339            106 => Self::MediumCloudUnknownType,
3340            107 => Self::HighCloudCumulus,
3341            108 => Self::HighCloudCirrus,
3342            109 => Self::HighCloudUnknownType,
3343            110 => Self::UnknownCloudType,
3344            111 => Self::SingleLayerWaterCloud,
3345            112 => Self::SingleLayerIceCloud,
3346            _ => Self::Missing,
3347        }
3348    }
3349}
3350impl core::fmt::Display for Grib2Table4_218 {
3351    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3352        let desc = match self {
3353            Self::NoSceneIdentified => "No Scene Identified",
3354            Self::GreenNeedleLeafedForest => "Green Needle-Leafed Forest",
3355            Self::GreenBroadLeafedForest => "Green Broad-Leafed Forest",
3356            Self::DeciduousNeedleLeafedForest => "Deciduous Needle-Leafed Forest",
3357            Self::DeciduousBroadLeafedForest => "Deciduous Broad-Leafed Forest",
3358            Self::DeciduousMixedForest => "Deciduous Mixed Forest",
3359            Self::ClosedShrubLand => "Closed Shrub-Land",
3360            Self::OpenShrubLand => "Open Shrub-Land",
3361            Self::WoodySavannah => "Woody Savannah",
3362            Self::Savannah => "Savannah",
3363            Self::Grassland => "Grassland",
3364            Self::PermanentWetland => "Permanent Wetland",
3365            Self::Cropland => "Cropland",
3366            Self::Urban => "Urban",
3367            Self::VegetationCrops => "Vegetation / Crops",
3368            Self::PermanentSnowIce => "Permanent Snow / Ice",
3369            Self::BarrenDesert => "Barren Desert",
3370            Self::WaterBodies => "Water Bodies",
3371            Self::Tundra => "Tundra",
3372            Self::WarmLiquidWaterCloud => "Warm Liquid Water Cloud",
3373            Self::SupercooledLiquidWaterCloud => "Supercooled Liquid Water Cloud",
3374            Self::MixedPhaseCloud => "Mixed Phase Cloud",
3375            Self::OpticallyThinIceCloud => "Optically Thin Ice Cloud",
3376            Self::OpticallyThickIceCloud => "Optically Thick Ice Cloud",
3377            Self::MultiLayerBlackCloud => "Multi-Layeblack Cloud",
3378            Self::SnowIceOnLand => "Snow / Ice on Land",
3379            Self::SnowIceOnWater => "Snow / Ice on Water",
3380            Self::SunGlint => "Sun-Glint",
3381            Self::GeneralCloud => "General Cloud",
3382            Self::LowCloudFogStratus => "Low Cloud / Fog / Stratus",
3383            Self::LowCloudStratocumulus => "Low Cloud / Stratocumulus",
3384            Self::LowCloudUnknownType => "Low Cloud / Unknown Type",
3385            Self::MediumCloudNimbostratus => "Medium Cloud / Nimbostratus",
3386            Self::MediumCloudAltostratus => "Medium Cloud / Altostratus",
3387            Self::MediumCloudUnknownType => "Medium Cloud / Unknown Type",
3388            Self::HighCloudCumulus => "High Cloud / Cumulus",
3389            Self::HighCloudCirrus => "High Cloud / Cirrus",
3390            Self::HighCloudUnknownType => "High Cloud / Unknown Type",
3391            Self::UnknownCloudType => "Unknown Cloud Type",
3392            Self::SingleLayerWaterCloud => "Single layer water cloud",
3393            Self::SingleLayerIceCloud => "Single layer ice cloud",
3394            Self::Missing => "Missing",
3395        };
3396        f.write_str(desc)
3397    }
3398}
3399
3400/// # GRIB2 - CODE TABLE 4.219 - CLOUD TOP HEIGHT QUALITY INDICATOR
3401///
3402/// **Details**:
3403/// - **Created**: 12/07/2010
3404///
3405/// **Reserved Ranges**:
3406/// - `4-191`: Reserved
3407/// - `192-254`: Reserved for Local Use
3408///
3409/// **Special Value**:
3410/// - `255`: Missing
3411///
3412/// ## Links
3413/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-219.shtml)
3414///
3415/// ## Notes
3416/// None.
3417#[repr(u8)]
3418#[allow(missing_docs)]
3419#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3420pub enum Grib2Table4_219 {
3421    NominalCloudTopHeightQuality = 0,
3422    FogInSegment = 1,
3423    PoorQualityHeightEstimation = 2,
3424    FogInSegmentAndPoorQualityHeightEstimation = 3,
3425    Missing = 255,
3426}
3427impl From<u8> for Grib2Table4_219 {
3428    fn from(val: u8) -> Self {
3429        match val {
3430            0 => Self::NominalCloudTopHeightQuality,
3431            1 => Self::FogInSegment,
3432            2 => Self::PoorQualityHeightEstimation,
3433            3 => Self::FogInSegmentAndPoorQualityHeightEstimation,
3434            _ => Self::Missing,
3435        }
3436    }
3437}
3438impl core::fmt::Display for Grib2Table4_219 {
3439    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3440        let desc = match self {
3441            Self::NominalCloudTopHeightQuality => "Nominal Cloud Top Height Quality",
3442            Self::FogInSegment => "Fog In Segment",
3443            Self::PoorQualityHeightEstimation => "Poor Quality Height Estimation",
3444            Self::FogInSegmentAndPoorQualityHeightEstimation => {
3445                "Fog In Segment and Poor Quality Height Estimation"
3446            }
3447            Self::Missing => "Missing",
3448        };
3449        f.write_str(desc)
3450    }
3451}
3452
3453/// # GRIB2 - CODE TABLE 4.220 - HORIZONTAL DIMENSION PROCESSED
3454///
3455/// **Details**:
3456/// - **Created**: 05/16/2005
3457///
3458/// **Reserved Ranges**:
3459/// - `2-191`: Reserved
3460/// - `192-254`: Reserved for Local Use
3461///
3462/// **Special Value**:
3463/// - `255`: Missing
3464///
3465/// ## Links
3466/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-220.shtml)
3467///
3468/// ## Notes
3469/// None.
3470#[repr(u8)]
3471#[allow(missing_docs)]
3472#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3473pub enum Grib2Table4_220 {
3474    Latitude = 0,
3475    Longitude = 1,
3476    Missing = 255,
3477}
3478impl From<u8> for Grib2Table4_220 {
3479    fn from(val: u8) -> Self {
3480        match val {
3481            0 => Self::Latitude,
3482            1 => Self::Longitude,
3483            _ => Self::Missing,
3484        }
3485    }
3486}
3487impl core::fmt::Display for Grib2Table4_220 {
3488    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3489        let desc = match self {
3490            Self::Latitude => "Latitude",
3491            Self::Longitude => "Longitude",
3492            Self::Missing => "Missing",
3493        };
3494        f.write_str(desc)
3495    }
3496}
3497
3498/// # GRIB2 - CODE TABLE 4.221 - TREATMENT OF MISSING DATA
3499///
3500/// **Details**:
3501/// - **Created**: 05/16/2005
3502///
3503/// **Reserved Ranges**:
3504/// - `2-191`: Reserved
3505/// - `192-254`: Reserved for Local Use
3506///
3507/// **Special Value**:
3508/// - `255`: Missing
3509///
3510/// ## Links
3511/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-221.shtml)
3512///
3513/// ## Notes
3514/// None.
3515#[repr(u8)]
3516#[allow(missing_docs)]
3517#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3518pub enum Grib2Table4_221 {
3519    NotIncluded = 0,
3520    Extrapolated = 1,
3521    Missing = 255,
3522}
3523impl From<u8> for Grib2Table4_221 {
3524    fn from(val: u8) -> Self {
3525        match val {
3526            0 => Self::NotIncluded,
3527            1 => Self::Extrapolated,
3528            _ => Self::Missing,
3529        }
3530    }
3531}
3532impl core::fmt::Display for Grib2Table4_221 {
3533    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3534        let desc = match self {
3535            Self::NotIncluded => "Not included",
3536            Self::Extrapolated => "Extrapolated",
3537            Self::Missing => "Missing",
3538        };
3539        f.write_str(desc)
3540    }
3541}
3542
3543/// # GRIB2 - CODE TABLE 4.222 - CATEGORICAL RESULT
3544///
3545/// **Details**:
3546/// - **Revised**: 07/16/2013
3547///
3548/// **Reserved Ranges**:
3549/// - `2-191`: Reserved
3550/// - `192-254`: Reserved for Local Use
3551///
3552/// **Special Value**:
3553/// - `255`: Missing
3554///
3555/// ## Links
3556/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-222.shtml)
3557///
3558/// ## Notes
3559/// None.
3560#[repr(u8)]
3561#[allow(missing_docs)]
3562#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3563pub enum Grib2Table4_222 {
3564    No = 0,
3565    Yes = 1,
3566    Missing = 255,
3567}
3568impl From<u8> for Grib2Table4_222 {
3569    fn from(val: u8) -> Self {
3570        match val {
3571            0 => Self::No,
3572            1 => Self::Yes,
3573            _ => Self::Missing,
3574        }
3575    }
3576}
3577impl core::fmt::Display for Grib2Table4_222 {
3578    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3579        let desc = match self {
3580            Self::No => "No",
3581            Self::Yes => "Yes",
3582            Self::Missing => "Missing",
3583        };
3584        f.write_str(desc)
3585    }
3586}
3587
3588/// # GRIB2 - CODE TABLE 4.223 - FIRE DETECTION INDICATOR
3589///
3590/// **Details**:
3591/// - **Created**: 11/05/2007
3592///
3593/// **Reserved Ranges**:
3594/// - `4-191`: Reserved
3595/// - `192-254`: Reserved for Local Use
3596///
3597/// **Special Value**:
3598/// - `255`: Missing
3599///
3600/// ## Links
3601/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-223.shtml)
3602///
3603/// ## Notes
3604/// None.
3605#[repr(u8)]
3606#[allow(missing_docs)]
3607#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3608pub enum Grib2Table4_223 {
3609    NoFireDetected = 0,
3610    PossibleFireDetected = 1,
3611    ProbableFireDetected = 2,
3612    MissingCode = 3, // Renamed to avoid conflict with the enum's Missing variant
3613    Missing = 255,
3614}
3615impl From<u8> for Grib2Table4_223 {
3616    fn from(val: u8) -> Self {
3617        match val {
3618            0 => Self::NoFireDetected,
3619            1 => Self::PossibleFireDetected,
3620            2 => Self::ProbableFireDetected,
3621            3 => Self::MissingCode,
3622            _ => Self::Missing,
3623        }
3624    }
3625}
3626impl core::fmt::Display for Grib2Table4_223 {
3627    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3628        let desc = match self {
3629            Self::NoFireDetected => "No Fire Detected",
3630            Self::PossibleFireDetected => "Possible Fire Detected",
3631            Self::ProbableFireDetected => "Probable Fire Detected",
3632            Self::MissingCode => "Missing",
3633            Self::Missing => "Missing",
3634        };
3635        f.write_str(desc)
3636    }
3637}
3638
3639/// # GRIB2 - CODE TABLE 4.224 - CATEGORICAL OUTLOOK
3640///
3641/// **Details**:
3642/// - **Created**: 12/21/2011
3643///
3644/// **Reserved Ranges**:
3645/// - `1`: Reserved
3646/// - `3`: Reserved
3647/// - `5`: Reserved
3648/// - `7`: Reserved
3649/// - `9-10`: Reserved
3650/// - `12-13`: Reserved
3651/// - `15-17`: Reserved
3652/// - `19-191`: Reserved
3653/// - `192-254`: Reserved for Local Use
3654///
3655/// **Special Value**:
3656/// - `255`: Missing
3657///
3658/// ## Links
3659/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-224.shtml)
3660///
3661/// ## Notes
3662/// None.
3663#[repr(u8)]
3664#[allow(missing_docs)]
3665#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3666pub enum Grib2Table4_224 {
3667    NoRiskArea = 0,
3668    GeneralThunderstormRiskArea = 2,
3669    SlightRiskArea = 4,
3670    ModerateRiskArea = 6,
3671    HighRiskArea = 8,
3672    DryThunderstormRiskArea = 11,
3673    CriticalRiskArea = 14,
3674    ExtremelyCriticalRiskArea = 18,
3675    Missing = 255,
3676}
3677impl From<u8> for Grib2Table4_224 {
3678    fn from(val: u8) -> Self {
3679        match val {
3680            0 => Self::NoRiskArea,
3681            2 => Self::GeneralThunderstormRiskArea,
3682            4 => Self::SlightRiskArea,
3683            6 => Self::ModerateRiskArea,
3684            8 => Self::HighRiskArea,
3685            11 => Self::DryThunderstormRiskArea,
3686            14 => Self::CriticalRiskArea,
3687            18 => Self::ExtremelyCriticalRiskArea,
3688            _ => Self::Missing,
3689        }
3690    }
3691}
3692impl core::fmt::Display for Grib2Table4_224 {
3693    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3694        let desc = match self {
3695            Self::NoRiskArea => "No Risk Area",
3696            Self::GeneralThunderstormRiskArea => "General Thunderstorm Risk Area",
3697            Self::SlightRiskArea => "Slight Risk Area",
3698            Self::ModerateRiskArea => "Moderate Risk Area",
3699            Self::HighRiskArea => "High Risk Area",
3700            Self::DryThunderstormRiskArea => "Dry Thunderstorm (Dry Lightning) Risk Area",
3701            Self::CriticalRiskArea => "Critical Risk Area",
3702            Self::ExtremelyCriticalRiskArea => "Extremely Critical Risk Area",
3703            Self::Missing => "Missing",
3704        };
3705        f.write_str(desc)
3706    }
3707}
3708
3709// TODO: GRIB2 - CODE TABLE 4.225 (https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-225.shtml)
3710
3711/// # GRIB2 - CODE TABLE 4.227 - ICING SCENARIO (Weather/Cloud Classification)
3712///
3713/// **Details**:
3714/// - **Created**: 04/09/2013
3715///
3716/// **Reserved Ranges**:
3717/// - `5-191`: Reserved
3718/// - `192-254`: Reserved for Local Use
3719///
3720/// **Special Value**:
3721/// - `255`: Missing
3722///
3723/// ## Links
3724/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-227.shtml)
3725///
3726/// ## Notes
3727/// None.
3728#[repr(u8)]
3729#[allow(missing_docs)]
3730#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3731pub enum Grib2Table4_227 {
3732    None = 0,
3733    General = 1,
3734    Convective = 2,
3735    Stratiform = 3,
3736    Freezing = 4,
3737    Missing = 255,
3738}
3739impl From<u8> for Grib2Table4_227 {
3740    fn from(val: u8) -> Self {
3741        match val {
3742            0 => Self::None,
3743            1 => Self::General,
3744            2 => Self::Convective,
3745            3 => Self::Stratiform,
3746            4 => Self::Freezing,
3747            _ => Self::Missing,
3748        }
3749    }
3750}
3751impl core::fmt::Display for Grib2Table4_227 {
3752    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3753        let desc = match self {
3754            Self::None => "None",
3755            Self::General => "General",
3756            Self::Convective => "Convective",
3757            Self::Stratiform => "Stratiform",
3758            Self::Freezing => "Freezing",
3759            Self::Missing => "Missing",
3760        };
3761        f.write_str(desc)
3762    }
3763}
3764
3765/// # GRIB2 - CODE TABLE 4.228 - ICING SEVERITY
3766///
3767/// **Details**:
3768/// - **Created**: 01/19/2022
3769///
3770/// **Reserved Ranges**:
3771/// - `6-191`: Reserved
3772/// - `192-254`: Reserved for Local Use
3773///
3774/// **Special Value**:
3775/// - `255`: Missing
3776///
3777/// ## Links
3778/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-228.shtml)
3779///
3780/// ## Notes
3781/// None.
3782#[repr(u8)]
3783#[allow(missing_docs)]
3784#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3785pub enum Grib2Table4_228 {
3786    None = 0,
3787    Trace = 1,
3788    Light = 2,
3789    Moderate = 3,
3790    Severe = 4,
3791    Missing = 255,
3792}
3793impl From<u8> for Grib2Table4_228 {
3794    fn from(val: u8) -> Self {
3795        match val {
3796            0 => Self::None,
3797            1 => Self::Trace,
3798            2 => Self::Light,
3799            3 => Self::Moderate,
3800            4 => Self::Severe,
3801            _ => Self::Missing,
3802        }
3803    }
3804}
3805impl core::fmt::Display for Grib2Table4_228 {
3806    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3807        let desc = match self {
3808            Self::None => "None",
3809            Self::Trace => "Trace",
3810            Self::Light => "Light",
3811            Self::Moderate => "Moderate",
3812            Self::Severe => "Severe",
3813            Self::Missing => "Missing",
3814        };
3815        f.write_str(desc)
3816    }
3817}
3818
3819/// # GRIB2 - CODE TABLE 4.230 - ATMOSPHERIC CHEMICAL OR PHYSICAL CONSTITUENT TYPE
3820///
3821/// **Details**:
3822/// - **Revised**: 04/12/2022
3823///
3824/// **Reserved Ranges**:
3825/// - `39-9999`: Reserved
3826/// - `10003`: Reserved
3827/// - `10024-10499`: Reserved
3828/// - `10501-20000`: Reserved
3829/// - `20022-29999`: Reserved
3830/// - `30001-50000`: Reserved
3831/// - `60017-61999`: Reserved
3832/// - `62035-65534`: Reserved
3833///
3834/// **Special Value**:
3835/// - `65535`: Missing
3836///
3837/// ## Links
3838/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-230.shtml)
3839/// - [More data...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/WMO306_vI2_CommonTable_en_v23.0.0.pdf)
3840#[repr(u16)] // Use u16 for values up to 65535
3841#[allow(missing_docs)]
3842#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3843pub enum Grib2Table4_230 {
3844    Ozone = 0,
3845    WaterVapour = 1,
3846    Methane = 2,
3847    CarbonDioxide = 3,
3848    CarbonMonoxide = 4,
3849    NitrogenDioxide = 5,
3850    NitrousOxide = 6,
3851    Formaldehyde = 7,
3852    SulphurDioxide = 8,
3853    Ammonia = 9,
3854    Ammonium = 10,
3855    NitrogenMonoxide = 11,
3856    AtomicOxygen = 12,
3857    NitrateRadical = 13,
3858    HydroperoxylRadical = 14,
3859    DinitrogenPentoxide = 15,
3860    NitrousAcid = 16,
3861    NitricAcid = 17,
3862    PeroxynitricAcid = 18,
3863    HydrogenPeroxide = 19,
3864    MolecularHydrogen = 20,
3865    AtomicNitrogen = 21,
3866    Sulphate = 22,
3867    Radon = 23,
3868    ElementalMercury = 24,
3869    DivalentMercury = 25,
3870    AtomicChlorine = 26,
3871    ChlorineMonoxide = 27,
3872    DichlorinePeroxide = 28,
3873    HypochlorousAcid = 29,
3874    ChlorineNitrate = 30,
3875    ChlorineDioxide = 31,
3876    AtomicBromide = 32,
3877    BromineMonoxide = 33,
3878    BromineChloride = 34,
3879    HydrogenBromide = 35,
3880    HypobromousAcid = 36,
3881    BromineNitrate = 37,
3882    Oxygen = 38,
3883    HydroxylRadical = 10000,
3884    MethylPeroxyRadical = 10001,
3885    MethylHydroperoxide = 10002,
3886    Methanol = 10004,
3887    FormicAcid = 10005,
3888    HydrogenCyanide = 10006,
3889    AcetoNitrile = 10007,
3890    Ethane = 10008,
3891    Ethene = 10009,
3892    Ethyne = 10010,
3893    Ethanol = 10011,
3894    AceticAcid = 10012,
3895    PeroxyacetylNitrate = 10013,
3896    Propane = 10014,
3897    Propene = 10015,
3898    Butanes = 10016,
3899    Isoprene = 10017,
3900    AlphaPinene = 10018,
3901    BetaPinene = 10019,
3902    Limonene = 10020,
3903    Benzene = 10021,
3904    Toluene = 10022,
3905    Xylene = 10023,
3906    DimethylSulphide = 10500,
3907    HydrogenChloride = 20001,
3908    CFC11 = 20002,
3909    CFC12 = 20003,
3910    CFC113 = 20004,
3911    CFC113a = 20005,
3912    CFC114 = 20006,
3913    CFC115 = 20007,
3914    HCFC22 = 20008,
3915    HCFC141b = 20009,
3916    HCFC142b = 20010,
3917    Halon1202 = 20011,
3918    Halon1211 = 20012,
3919    Halon1301 = 20013,
3920    Halon2402 = 20014,
3921    MethylChloride = 20015,
3922    CarbonTetrachloride = 20016,
3923    HCC140a = 20017,
3924    MethylBromide = 20018,
3925    Hexachlorocyclohexane = 20019,
3926    AlphaHexachlorocyclohexane = 20020,
3927    Hexachlorobiphenyl = 20021,
3928    RadioactivePollutant = 30000,
3929    HOxRadical = 60000,
3930    TotalInorganicAndOrganicPeroxyRadicals = 60001,
3931    PassiveOzone = 60002,
3932    NOxExpressedAsNitrogen = 60003,
3933    AllNitrogenOxides = 60004,
3934    TotalInorganicChlorine = 60005,
3935    TotalInorganicBromine = 60006,
3936    TotalInorganicChlorineExceptHClClONO2 = 60007,
3937    TotalInorganicBromineExceptHBrBrONO2 = 60008,
3938    LumpedAlkanes = 60009,
3939    LumpedAlkenes = 60010,
3940    LumpedAromaticCompounds = 60011,
3941    LumpedTerpenes = 60012,
3942    NonMethaneVolatileOrganicCompounds = 60013,
3943    AnthropogenicNonMethaneVolatileOrganicCompounds = 60014,
3944    BiogenicNonMethaneVolatileOrganicCompounds = 60015,
3945    LumpedOxygenatedHydrocarbons = 60016,
3946    TotalAerosol = 62000,
3947    DustDry = 62001,
3948    WaterInAmbient = 62002,
3949    AmmoniumDry = 62003,
3950    NitrateDry = 62004,
3951    NitricAcidTrihydrate = 62005,
3952    SulphateDry = 62006,
3953    MercuryDry = 62007,
3954    SeaSaltDry = 62008,
3955    BlackCarbonDry = 62009,
3956    ParticulateOrganicMatterDry = 62010,
3957    PrimaryParticulateOrganicMatterDry = 62011,
3958    SecondaryParticulateOrganicMatterDry = 62012,
3959    BrownCarbonDry = 62034,
3960    Missing = 65535,
3961}
3962impl From<u16> for Grib2Table4_230 {
3963    fn from(val: u16) -> Self {
3964        match val {
3965            0 => Self::Ozone,
3966            1 => Self::WaterVapour,
3967            2 => Self::Methane,
3968            3 => Self::CarbonDioxide,
3969            4 => Self::CarbonMonoxide,
3970            5 => Self::NitrogenDioxide,
3971            6 => Self::NitrousOxide,
3972            7 => Self::Formaldehyde,
3973            8 => Self::SulphurDioxide,
3974            9 => Self::Ammonia,
3975            10 => Self::Ammonium,
3976            11 => Self::NitrogenMonoxide,
3977            12 => Self::AtomicOxygen,
3978            13 => Self::NitrateRadical,
3979            14 => Self::HydroperoxylRadical,
3980            15 => Self::DinitrogenPentoxide,
3981            16 => Self::NitrousAcid,
3982            17 => Self::NitricAcid,
3983            18 => Self::PeroxynitricAcid,
3984            19 => Self::HydrogenPeroxide,
3985            20 => Self::MolecularHydrogen,
3986            21 => Self::AtomicNitrogen,
3987            22 => Self::Sulphate,
3988            23 => Self::Radon,
3989            24 => Self::ElementalMercury,
3990            25 => Self::DivalentMercury,
3991            26 => Self::AtomicChlorine,
3992            27 => Self::ChlorineMonoxide,
3993            28 => Self::DichlorinePeroxide,
3994            29 => Self::HypochlorousAcid,
3995            30 => Self::ChlorineNitrate,
3996            31 => Self::ChlorineDioxide,
3997            32 => Self::AtomicBromide,
3998            33 => Self::BromineMonoxide,
3999            34 => Self::BromineChloride,
4000            35 => Self::HydrogenBromide,
4001            36 => Self::HypobromousAcid,
4002            37 => Self::BromineNitrate,
4003            38 => Self::Oxygen,
4004            10000 => Self::HydroxylRadical,
4005            10001 => Self::MethylPeroxyRadical,
4006            10002 => Self::MethylHydroperoxide,
4007            10004 => Self::Methanol,
4008            10005 => Self::FormicAcid,
4009            10006 => Self::HydrogenCyanide,
4010            10007 => Self::AcetoNitrile,
4011            10008 => Self::Ethane,
4012            10009 => Self::Ethene,
4013            10010 => Self::Ethyne,
4014            10011 => Self::Ethanol,
4015            10012 => Self::AceticAcid,
4016            10013 => Self::PeroxyacetylNitrate,
4017            10014 => Self::Propane,
4018            10015 => Self::Propene,
4019            10016 => Self::Butanes,
4020            10017 => Self::Isoprene,
4021            10018 => Self::AlphaPinene,
4022            10019 => Self::BetaPinene,
4023            10020 => Self::Limonene,
4024            10021 => Self::Benzene,
4025            10022 => Self::Toluene,
4026            10023 => Self::Xylene,
4027            10500 => Self::DimethylSulphide,
4028            20001 => Self::HydrogenChloride,
4029            20002 => Self::CFC11,
4030            20003 => Self::CFC12,
4031            20004 => Self::CFC113,
4032            20005 => Self::CFC113a,
4033            20006 => Self::CFC114,
4034            20007 => Self::CFC115,
4035            20008 => Self::HCFC22,
4036            20009 => Self::HCFC141b,
4037            20010 => Self::HCFC142b,
4038            20011 => Self::Halon1202,
4039            20012 => Self::Halon1211,
4040            20013 => Self::Halon1301,
4041            20014 => Self::Halon2402,
4042            20015 => Self::MethylChloride,
4043            20016 => Self::CarbonTetrachloride,
4044            20017 => Self::HCC140a,
4045            20018 => Self::MethylBromide,
4046            20019 => Self::Hexachlorocyclohexane,
4047            20020 => Self::AlphaHexachlorocyclohexane,
4048            20021 => Self::Hexachlorobiphenyl,
4049            30000 => Self::RadioactivePollutant,
4050            60000 => Self::HOxRadical,
4051            60001 => Self::TotalInorganicAndOrganicPeroxyRadicals,
4052            60002 => Self::PassiveOzone,
4053            60003 => Self::NOxExpressedAsNitrogen,
4054            60004 => Self::AllNitrogenOxides,
4055            60005 => Self::TotalInorganicChlorine,
4056            60006 => Self::TotalInorganicBromine,
4057            60007 => Self::TotalInorganicChlorineExceptHClClONO2,
4058            60008 => Self::TotalInorganicBromineExceptHBrBrONO2,
4059            60009 => Self::LumpedAlkanes,
4060            60010 => Self::LumpedAlkenes,
4061            60011 => Self::LumpedAromaticCompounds,
4062            60012 => Self::LumpedTerpenes,
4063            60013 => Self::NonMethaneVolatileOrganicCompounds,
4064            60014 => Self::AnthropogenicNonMethaneVolatileOrganicCompounds,
4065            60015 => Self::BiogenicNonMethaneVolatileOrganicCompounds,
4066            60016 => Self::LumpedOxygenatedHydrocarbons,
4067            62000 => Self::TotalAerosol,
4068            62001 => Self::DustDry,
4069            62002 => Self::WaterInAmbient,
4070            62003 => Self::AmmoniumDry,
4071            62004 => Self::NitrateDry,
4072            62005 => Self::NitricAcidTrihydrate,
4073            62006 => Self::SulphateDry,
4074            62007 => Self::MercuryDry,
4075            62008 => Self::SeaSaltDry,
4076            62009 => Self::BlackCarbonDry,
4077            62010 => Self::ParticulateOrganicMatterDry,
4078            62011 => Self::PrimaryParticulateOrganicMatterDry,
4079            62012 => Self::SecondaryParticulateOrganicMatterDry,
4080            62034 => Self::BrownCarbonDry,
4081            _ => Self::Missing,
4082        }
4083    }
4084}
4085impl core::fmt::Display for Grib2Table4_230 {
4086    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4087        let desc = match self {
4088            Self::Ozone => "Ozone - O3",
4089            Self::WaterVapour => "Water Vapour - H2O",
4090            Self::Methane => "Methane - CH4",
4091            Self::CarbonDioxide => "Carbon Dioxide - CO2",
4092            Self::CarbonMonoxide => "Carbon Monoxide - CO",
4093            Self::NitrogenDioxide => "Nitrogen Dioxide - NO2",
4094            Self::NitrousOxide => "Nitrous Oxide - N2O",
4095            Self::Formaldehyde => "Formaldehyde - HCHO",
4096            Self::SulphurDioxide => "Sulphur Dioxide - SO2",
4097            Self::Ammonia => "Ammonia - NH3",
4098            Self::Ammonium => "Ammonium - NH4+",
4099            Self::NitrogenMonoxide => "Nitrogen Monoxide - NO",
4100            Self::AtomicOxygen => "Atomic Oxygen - O",
4101            Self::NitrateRadical => "Nitrate Radical - NO3",
4102            Self::HydroperoxylRadical => "Hydroperoxyl Radical - HO2",
4103            Self::DinitrogenPentoxide => "Dinitrogen Pentoxide - H2O5",
4104            Self::NitrousAcid => "Nitrous Acid - HONO",
4105            Self::NitricAcid => "Nitric Acid - HNO3",
4106            Self::PeroxynitricAcid => "Peroxynitric Acid - HO2NO2",
4107            Self::HydrogenPeroxide => "Hydrogen Peroxide - H2O2",
4108            Self::MolecularHydrogen => "Molecular Hydrogen - H",
4109            Self::AtomicNitrogen => "Atomic Nitrogen - N",
4110            Self::Sulphate => "Sulphate - SO42-",
4111            Self::Radon => "Radon - Rn",
4112            Self::ElementalMercury => "Elemental Mercury - Hg(O)",
4113            Self::DivalentMercury => "Divalent Mercury - Hg2+",
4114            Self::AtomicChlorine => "Atomic Chlorine - Cl",
4115            Self::ChlorineMonoxide => "Chlorine Monoxide - ClO",
4116            Self::DichlorinePeroxide => "Dichlorine Peroxide - Cl2O2",
4117            Self::HypochlorousAcid => "Hypochlorous Acid - HClO",
4118            Self::ChlorineNitrate => "Chlorine Nitrate - ClONO2",
4119            Self::ChlorineDioxide => "Chlorine Dioxide - ClO2",
4120            Self::AtomicBromide => "Atomic Bromide - Br",
4121            Self::BromineMonoxide => "Bromine Monoxide - BrO",
4122            Self::BromineChloride => "Bromine Chloride - BrCl",
4123            Self::HydrogenBromide => "Hydrogen Bromide - HBr",
4124            Self::HypobromousAcid => "Hypobromous Acid - HBrO",
4125            Self::BromineNitrate => "Bromine Nitrate - BrONO2",
4126            Self::Oxygen => "Oxygen - O2",
4127            Self::HydroxylRadical => "Hydroxyl Radical - OH",
4128            Self::MethylPeroxyRadical => "Methyl Peroxy Radical - CH3O2",
4129            Self::MethylHydroperoxide => "Methyl Hydroperoxide - CH3O2H",
4130            Self::Methanol => "Methanol - CH3OH",
4131            Self::FormicAcid => "Formic Acid - CH3OOH",
4132            Self::HydrogenCyanide => "Hydrogen Cyanide - HCN",
4133            Self::AcetoNitrile => "Aceto Nitrile - CH3CN",
4134            Self::Ethane => "Ethane - C2H6",
4135            Self::Ethene => "Ethene (Ethylene) - C2H4",
4136            Self::Ethyne => "Ethyne (Acetylene) - C2H2",
4137            Self::Ethanol => "Ethanol - C2H5OH",
4138            Self::AceticAcid => "Acetic Acid - C2H5OOH",
4139            Self::PeroxyacetylNitrate => "Peroxyacetyl Nitrate - CH3C(O)OONO2",
4140            Self::Propane => "Propane - C3H8",
4141            Self::Propene => "Propene - C3H6",
4142            Self::Butanes => "Butanes - C4H10",
4143            Self::Isoprene => "Isoprene - C5H10",
4144            Self::AlphaPinene => "Alpha Pinene - C10H16",
4145            Self::BetaPinene => "Beta Pinene - C10H16",
4146            Self::Limonene => "Limonene - C10H16",
4147            Self::Benzene => "Benzene - C6H6",
4148            Self::Toluene => "Toluene - C7H8",
4149            Self::Xylene => "Xylene - C8H10",
4150            Self::DimethylSulphide => "Dimethyl Sulphide - CH3SCH3",
4151            Self::HydrogenChloride => "Hydrogen Chloride - HCL",
4152            Self::CFC11 => "CFC-11",
4153            Self::CFC12 => "CFC-12",
4154            Self::CFC113 => "CFC-113",
4155            Self::CFC113a => "CFC-113a",
4156            Self::CFC114 => "CFC-114",
4157            Self::CFC115 => "CFC-115",
4158            Self::HCFC22 => "HCFC-22",
4159            Self::HCFC141b => "HCFC-141b",
4160            Self::HCFC142b => "HCFC-142b",
4161            Self::Halon1202 => "Halon-1202",
4162            Self::Halon1211 => "Halon-1211",
4163            Self::Halon1301 => "Halon-1301",
4164            Self::Halon2402 => "Halon-2402",
4165            Self::MethylChloride => "Methyl Chloride (HCC-40)",
4166            Self::CarbonTetrachloride => "Carbon Tetrachloride (HCC-10)",
4167            Self::HCC140a => "HCC-140a - CH3CCl3",
4168            Self::MethylBromide => "Methyl Bromide (HBC-40B1)",
4169            Self::Hexachlorocyclohexane => "Hexachlorocyclohexane (HCH)",
4170            Self::AlphaHexachlorocyclohexane => "Alpha Hexachlorocyclohexane",
4171            Self::Hexachlorobiphenyl => "Hexachlorobiphenyl (PCB-153)",
4172            Self::RadioactivePollutant => {
4173                "Radioactive Pollutant (Tracer, defined by originating centre)"
4174            }
4175            Self::HOxRadical => "HOx Radical (OH+HO2)",
4176            Self::TotalInorganicAndOrganicPeroxyRadicals => {
4177                "Total Inorganic and Organic Peroxy Radicals (HO2+RO2) - RO2"
4178            }
4179            Self::PassiveOzone => "Passive Ozone",
4180            Self::NOxExpressedAsNitrogen => "NOx Expressed As Nitrogen - NOx",
4181            Self::AllNitrogenOxides => "All Nitrogen Oxides (NOy) Expressed As Nitrogen - NOy",
4182            Self::TotalInorganicChlorine => "Total Inorganic Chlorine - Clx",
4183            Self::TotalInorganicBromine => "Total Inorganic Bromine - Brx",
4184            Self::TotalInorganicChlorineExceptHClClONO2 => {
4185                "Total Inorganic Chlorine Except HCl, ClONO2: ClOx"
4186            }
4187            Self::TotalInorganicBromineExceptHBrBrONO2 => {
4188                "Total Inorganic Bromine Except HBr, BrONO2: BrOx"
4189            }
4190            Self::LumpedAlkanes => "Lumped Alkanes",
4191            Self::LumpedAlkenes => "Lumped Alkenes",
4192            Self::LumpedAromaticCompounds => "Lumped Aromatic Compounds",
4193            Self::LumpedTerpenes => "Lumped Terpenes",
4194            Self::NonMethaneVolatileOrganicCompounds => {
4195                "Non-Methane Volatile Organic Compounds Expressed as Carbon - NMVOC"
4196            }
4197            Self::AnthropogenicNonMethaneVolatileOrganicCompounds => {
4198                "Anthropogenic Non-Methane Volatile Organic Compounds Expressed as Carbon - aNMVOC"
4199            }
4200            Self::BiogenicNonMethaneVolatileOrganicCompounds => {
4201                "Biogenic Non-Methane Volatile Organic Compounds Expressed as Carbon - bNMVOC"
4202            }
4203            Self::LumpedOxygenatedHydrocarbons => "Lumped Oxygenated Hydrocarbons - OVOC",
4204            Self::TotalAerosol => "Total Aerosol",
4205            Self::DustDry => "Dust Dry",
4206            Self::WaterInAmbient => "Water In Ambient",
4207            Self::AmmoniumDry => "Ammonium Dry",
4208            Self::NitrateDry => "Nitrate Dry",
4209            Self::NitricAcidTrihydrate => "Nitric Acid Trihydrate",
4210            Self::SulphateDry => "Sulphate Dry",
4211            Self::MercuryDry => "Mercury Dry",
4212            Self::SeaSaltDry => "Sea Salt Dry",
4213            Self::BlackCarbonDry => "Black Carbon Dry",
4214            Self::ParticulateOrganicMatterDry => "Particulate Organic Matter Dry",
4215            Self::PrimaryParticulateOrganicMatterDry => "Primary Particulate Organic Matter Dry",
4216            Self::SecondaryParticulateOrganicMatterDry => {
4217                "Secondary Particulate Organic Matter Dry"
4218            }
4219            Self::BrownCarbonDry => "Brown Carbon Dry",
4220            Self::Missing => "Missing",
4221        };
4222        f.write_str(desc)
4223    }
4224}
4225
4226/// GRIB2 - CODE TABLE 4.233: AEROSOL TYPE
4227///
4228/// **Created**: 05/16/2005
4229/// **Revised**: 07/18/2022
4230///
4231/// ## Links
4232/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-233.shtml)
4233/// - [More data...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/WMO306_vI2_CommonTable_en_v23.0.0.pdf)
4234///
4235/// ## Notes
4236/// Red text depicts changes made since 05/29/2019.
4237#[repr(u16)]
4238#[allow(missing_docs)]
4239#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4240pub enum Grib2Table4_233 {
4241    Ozone = 0,
4242    WaterVapour = 1,
4243    Methane = 2,
4244    CarbonDioxide = 3,
4245    CarbonMonoxide = 4,
4246    NitrogenDioxide = 5,
4247    NitrousOxide = 6,
4248    Formaldehyde = 7,
4249    SulphurDioxide = 8,
4250    Ammonia = 9,
4251    Ammonium = 10,
4252    NitrogenMonoxide = 11,
4253    AtomicOxygen = 12,
4254    NitrateRadical = 13,
4255    HydroperoxylRadical = 14,
4256    DinitrogenPentoxide = 15,
4257    NitrousAcid = 16,
4258    NitricAcid = 17,
4259    PeroxynitricAcid = 18,
4260    HydrogenPeroxide = 19,
4261    MolecularHydrogen = 20,
4262    AtomicNitrogen = 21,
4263    Sulphate = 22,
4264    Radon = 23,
4265    ElementalMercury = 24,
4266    DivalentMercury = 25,
4267    AtomicChlorine = 26,
4268    ChlorineMonoxide = 27,
4269    DichlorinePeroxide = 28,
4270    HypochlorousAcid = 29,
4271    ChlorineNitrate = 30,
4272    ChlorineDioxide = 31,
4273    AtomicBromide = 32,
4274    BromineMonoxide = 33,
4275    BromineChloride = 34,
4276    HydrogenBromide = 35,
4277    HypobromousAcid = 36,
4278    BromineNitrate = 37,
4279    Oxygen = 38,
4280    Reserved39 = 39,
4281    HydroxylRadical = 10000,
4282    MethylPeroxyRadical = 10001,
4283    MethylHydroperoxide = 10002,
4284    Reserved10003 = 10003,
4285    Methanol = 10004,
4286    FormicAcid = 10005,
4287    HydrogenCyanide = 10006,
4288    AcetoNitrile = 10007,
4289    Ethane = 10008,
4290    Ethene = 10009,
4291    Ethyne = 10010,
4292    Ethanol = 10011,
4293    AceticAcid = 10012,
4294    PeroxyacetylNitrate = 10013,
4295    Propane = 10014,
4296    Propene = 10015,
4297    Butanes = 10016,
4298    Isoprene = 10017,
4299    AlphaPinene = 10018,
4300    BetaPinene = 10019,
4301    Limonene = 10020,
4302    Benzene = 10021,
4303    Toluene = 10022,
4304    Xylene = 10023,
4305    Reserved10024 = 10024,
4306    DimethylSulphide = 10500,
4307    HydrogenChloride = 20001,
4308    CFC11 = 20002,
4309    CFC12 = 20003,
4310    CFC113 = 20004,
4311    CFC113a = 20005,
4312    CFC114 = 20006,
4313    CFC115 = 20007,
4314    HCFC22 = 20008,
4315    HCFC141b = 20009,
4316    HCFC142b = 20010,
4317    Halon1202 = 20011,
4318    Halon1211 = 20012,
4319    Halon1301 = 20013,
4320    Halon2402 = 20014,
4321    MethylChloride = 20015,
4322    CarbonTetrachloride = 20016,
4323    HCC140a = 20017,
4324    MethylBromide = 20018,
4325    Hexachlorocyclohexane = 20019,
4326    AlphaHexachlorocyclohexane = 20020,
4327    Hexachlorobiphenyl = 20021,
4328    RadioactivePollutant = 30000,
4329    HOxRadical = 60000,
4330    TotalInorganicAndOrganicPeroxyRadicals = 60001,
4331    PassiveOzone = 60002,
4332    NOxExpressedAsNitrogen = 60003,
4333    AllNitrogenOxides = 60004,
4334    TotalInorganicChlorineExceptHClClONO2 = 60005,
4335    TotalInorganicBromineExceptHBrBrONO2 = 60006,
4336    LumpedAlkanes = 60007,
4337    LumpedAlkenes = 60008,
4338    LumpedAromaticCompounds = 60009,
4339    LumpedTerpenes = 60010,
4340    NonMethaneVolatileOrganicCompounds = 60011,
4341    AnthropogenicNMVOCExpressedAsCarbon = 60012,
4342    BiogenicNMVOCExpressedAsCarbon = 60013,
4343    LumpedOxygenatedHydrocarbons = 60014,
4344    Reserved60015 = 60015,
4345    TotalAerosol = 62000,
4346    DustDry = 62001,
4347    WaterInAmbient = 62002,
4348    AmmoniumDry = 62003,
4349    NitrateDry = 62004,
4350    NitricAcidTrihydrate = 62005,
4351    SulphateDry = 62006,
4352    MercuryDry = 62007,
4353    SeaSaltDry = 62008,
4354    BlackCarbonDry = 62009,
4355    ParticulateOrganicMatterDry = 62010,
4356    PrimaryParticulateOrganicMatterDry = 62011,
4357    SecondaryParticulateOrganicMatterDry = 62012,
4358    BlackCarbonHydrophilicDry = 62013,
4359    BlackCarbonHydrophobicDry = 62014,
4360    ParticulateOrganicMatterHydrophilicDry = 62015,
4361    ParticulateOrganicMatterHydrophobicDry = 62016,
4362    NitrateHydrophilicDry = 62017,
4363    NitrateHydrophobicDry = 62018,
4364    Reserved62019 = 62019,
4365    SmokeHighAbsorption = 62020,
4366    SmokeLowAbsorption = 62021,
4367    AerosolHighAbsorption = 62022,
4368    AerosolLowAbsorption = 62023,
4369    Reserved62024 = 62024,
4370    VolcanicAsh = 62025,
4371    BrownCarbonDry = 62036,
4372    Missing = 65535,
4373}
4374impl From<u16> for Grib2Table4_233 {
4375    fn from(val: u16) -> Self {
4376        match val {
4377            0 => Self::Ozone,
4378            1 => Self::WaterVapour,
4379            2 => Self::Methane,
4380            3 => Self::CarbonDioxide,
4381            4 => Self::CarbonMonoxide,
4382            5 => Self::NitrogenDioxide,
4383            6 => Self::NitrousOxide,
4384            7 => Self::Formaldehyde,
4385            8 => Self::SulphurDioxide,
4386            9 => Self::Ammonia,
4387            10 => Self::Ammonium,
4388            11 => Self::NitrogenMonoxide,
4389            12 => Self::AtomicOxygen,
4390            13 => Self::NitrateRadical,
4391            14 => Self::HydroperoxylRadical,
4392            15 => Self::DinitrogenPentoxide,
4393            16 => Self::NitrousAcid,
4394            17 => Self::NitricAcid,
4395            18 => Self::PeroxynitricAcid,
4396            19 => Self::HydrogenPeroxide,
4397            20 => Self::MolecularHydrogen,
4398            21 => Self::AtomicNitrogen,
4399            22 => Self::Sulphate,
4400            23 => Self::Radon,
4401            24 => Self::ElementalMercury,
4402            25 => Self::DivalentMercury,
4403            26 => Self::AtomicChlorine,
4404            27 => Self::ChlorineMonoxide,
4405            28 => Self::DichlorinePeroxide,
4406            29 => Self::HypochlorousAcid,
4407            30 => Self::ChlorineNitrate,
4408            31 => Self::ChlorineDioxide,
4409            32 => Self::AtomicBromide,
4410            33 => Self::BromineMonoxide,
4411            34 => Self::BromineChloride,
4412            35 => Self::HydrogenBromide,
4413            36 => Self::HypobromousAcid,
4414            37 => Self::BromineNitrate,
4415            38 => Self::Oxygen,
4416            39 => Self::Reserved39,
4417            10000 => Self::HydroxylRadical,
4418            10001 => Self::MethylPeroxyRadical,
4419            10002 => Self::MethylHydroperoxide,
4420            10003 => Self::Reserved10003,
4421            10004 => Self::Methanol,
4422            10005 => Self::FormicAcid,
4423            10006 => Self::HydrogenCyanide,
4424            10007 => Self::AcetoNitrile,
4425            10008 => Self::Ethane,
4426            10009 => Self::Ethene,
4427            10010 => Self::Ethyne,
4428            10011 => Self::Ethanol,
4429            10012 => Self::AceticAcid,
4430            10013 => Self::PeroxyacetylNitrate,
4431            10014 => Self::Propane,
4432            10015 => Self::Propene,
4433            10016 => Self::Butanes,
4434            10017 => Self::Isoprene,
4435            10018 => Self::AlphaPinene,
4436            10019 => Self::BetaPinene,
4437            10020 => Self::Limonene,
4438            10021 => Self::Benzene,
4439            10022 => Self::Toluene,
4440            10023 => Self::Xylene,
4441            10024 => Self::Reserved10024,
4442            10500 => Self::DimethylSulphide,
4443            20001 => Self::HydrogenChloride,
4444            20002 => Self::CFC11,
4445            20003 => Self::CFC12,
4446            20004 => Self::CFC113,
4447            20005 => Self::CFC113a,
4448            20006 => Self::CFC114,
4449            20007 => Self::CFC115,
4450            20008 => Self::HCFC22,
4451            20009 => Self::HCFC141b,
4452            20010 => Self::HCFC142b,
4453            20011 => Self::Halon1202,
4454            20012 => Self::Halon1211,
4455            20013 => Self::Halon1301,
4456            20014 => Self::Halon2402,
4457            20015 => Self::MethylChloride,
4458            20016 => Self::CarbonTetrachloride,
4459            20017 => Self::HCC140a,
4460            20018 => Self::MethylBromide,
4461            20019 => Self::Hexachlorocyclohexane,
4462            20020 => Self::AlphaHexachlorocyclohexane,
4463            20021 => Self::Hexachlorobiphenyl,
4464            30000 => Self::RadioactivePollutant,
4465            60000 => Self::HOxRadical,
4466            60001 => Self::TotalInorganicAndOrganicPeroxyRadicals,
4467            60002 => Self::PassiveOzone,
4468            60003 => Self::NOxExpressedAsNitrogen,
4469            60004 => Self::AllNitrogenOxides,
4470            60005 => Self::TotalInorganicChlorineExceptHClClONO2,
4471            60006 => Self::TotalInorganicBromineExceptHBrBrONO2,
4472            60007 => Self::LumpedAlkanes,
4473            60008 => Self::LumpedAlkenes,
4474            60009 => Self::LumpedAromaticCompounds,
4475            60010 => Self::LumpedTerpenes,
4476            60011 => Self::NonMethaneVolatileOrganicCompounds,
4477            60012 => Self::AnthropogenicNMVOCExpressedAsCarbon,
4478            60013 => Self::BiogenicNMVOCExpressedAsCarbon,
4479            60014 => Self::LumpedOxygenatedHydrocarbons,
4480            60015 => Self::Reserved60015,
4481            62000 => Self::TotalAerosol,
4482            62001 => Self::DustDry,
4483            62002 => Self::WaterInAmbient,
4484            62003 => Self::AmmoniumDry,
4485            62004 => Self::NitrateDry,
4486            62005 => Self::NitricAcidTrihydrate,
4487            62006 => Self::SulphateDry,
4488            62007 => Self::MercuryDry,
4489            62008 => Self::SeaSaltDry,
4490            62009 => Self::BlackCarbonDry,
4491            62010 => Self::ParticulateOrganicMatterDry,
4492            62011 => Self::PrimaryParticulateOrganicMatterDry,
4493            62012 => Self::SecondaryParticulateOrganicMatterDry,
4494            62013 => Self::BlackCarbonHydrophilicDry,
4495            62014 => Self::BlackCarbonHydrophobicDry,
4496            62015 => Self::ParticulateOrganicMatterHydrophilicDry,
4497            62016 => Self::ParticulateOrganicMatterHydrophobicDry,
4498            62017 => Self::NitrateHydrophilicDry,
4499            62018 => Self::NitrateHydrophobicDry,
4500            62019 => Self::Reserved62019,
4501            62020 => Self::SmokeHighAbsorption,
4502            62021 => Self::SmokeLowAbsorption,
4503            62022 => Self::AerosolHighAbsorption,
4504            62023 => Self::AerosolLowAbsorption,
4505            62024 => Self::Reserved62024,
4506            62025 => Self::VolcanicAsh,
4507            62036 => Self::BrownCarbonDry,
4508            _ => Self::Missing,
4509        }
4510    }
4511}
4512impl core::fmt::Display for Grib2Table4_233 {
4513    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4514        let desc = match self {
4515            Self::Ozone => "Ozone - O3",
4516            Self::WaterVapour => "Water Vapour - H2O",
4517            Self::Methane => "Methane - CH4",
4518            Self::CarbonDioxide => "Carbon Dioxide - CO2",
4519            Self::CarbonMonoxide => "Carbon Monoxide - CO",
4520            Self::NitrogenDioxide => "Nitrogen Dioxide - NO2",
4521            Self::NitrousOxide => "Nitrous Oxide - N2O",
4522            Self::Formaldehyde => "Formaldehyde - HCHO",
4523            Self::SulphurDioxide => "Sulphur Dioxide - SO2",
4524            Self::Ammonia => "Ammonia - NH3",
4525            Self::Ammonium => "Ammonium - NH4+",
4526            Self::NitrogenMonoxide => "Nitrogen Monoxide - NO",
4527            Self::AtomicOxygen => "Atomic Oxygen - O",
4528            Self::NitrateRadical => "Nitrate Radical - NO3",
4529            Self::HydroperoxylRadical => "Hydroperoxyl Radical - HO2",
4530            Self::DinitrogenPentoxide => "Dinitrogen Pentoxide - H2O5",
4531            Self::NitrousAcid => "Nitrous Acid - HONO",
4532            Self::NitricAcid => "Nitric Acid - HNO3",
4533            Self::PeroxynitricAcid => "Peroxynitric Acid - HO2NO2",
4534            Self::HydrogenPeroxide => "Hydrogen Peroxide - H2O2",
4535            Self::MolecularHydrogen => "Molecular Hydrogen - H",
4536            Self::AtomicNitrogen => "Atomic Nitrogen - N",
4537            Self::Sulphate => "Sulphate - SO42-",
4538            Self::Radon => "Radon - Rn",
4539            Self::ElementalMercury => "Elemental Mercury - Hg(O)",
4540            Self::DivalentMercury => "Divalent Mercury - Hg2+",
4541            Self::AtomicChlorine => "Atomic Chlorine - Cl",
4542            Self::ChlorineMonoxide => "Chlorine Monoxide - ClO",
4543            Self::DichlorinePeroxide => "Dichlorine Peroxide - Cl2O2",
4544            Self::HypochlorousAcid => "Hypochlorous Acid - HClO",
4545            Self::ChlorineNitrate => "Chlorine Nitrate - ClONO2",
4546            Self::ChlorineDioxide => "Chlorine Dioxide - ClO2",
4547            Self::AtomicBromide => "Atomic Bromide - Br",
4548            Self::BromineMonoxide => "Bromine Monoxide - BrO",
4549            Self::BromineChloride => "Bromine Chloride - BrCl",
4550            Self::HydrogenBromide => "Hydrogen Bromide - HBr",
4551            Self::HypobromousAcid => "Hypobromous Acid - HBrO",
4552            Self::BromineNitrate => "Bromine Nitrate - BrONO2",
4553            Self::Oxygen => "Oxygen - O2",
4554            Self::Reserved39 => "Reserved",
4555            Self::HydroxylRadical => "Hydroxyl Radical - OH",
4556            Self::MethylPeroxyRadical => "Methyl Peroxy Radical - CH3O2",
4557            Self::MethylHydroperoxide => "Methyl Hydroperoxide - CH3O2H",
4558            Self::Reserved10003 => "Reserved",
4559            Self::Methanol => "Methanol - CH3OH",
4560            Self::FormicAcid => "Formic Acid - CH3OOH",
4561            Self::HydrogenCyanide => "Hydrogen Cyanide - HCN",
4562            Self::AcetoNitrile => "Aceto Nitrile - CH3CN",
4563            Self::Ethane => "Ethane - C2H6",
4564            Self::Ethene => "Ethene (Ethylene) - C2H4",
4565            Self::Ethyne => "Ethyne (Acetylene) - C2H2",
4566            Self::Ethanol => "Ethanol - C2H5OH",
4567            Self::AceticAcid => "Acetic Acid - C2H5OOH",
4568            Self::PeroxyacetylNitrate => "Peroxyacetyl Nitrate - CH3C(O)OONO2",
4569            Self::Propane => "Propane - C3H8",
4570            Self::Propene => "Propene - C3H6",
4571            Self::Butanes => "Butanes - C4H10",
4572            Self::Isoprene => "Isoprene - C5H10",
4573            Self::AlphaPinene => "Alpha Pinene - C10H16",
4574            Self::BetaPinene => "Beta Pinene - C10H16",
4575            Self::Limonene => "Limonene - C10H16",
4576            Self::Benzene => "Benzene - C6H6",
4577            Self::Toluene => "Toluene - C7H8",
4578            Self::Xylene => "Xylene - C8H10",
4579            Self::Reserved10024 => "Reserved",
4580            Self::DimethylSulphide => "Dimethyl Sulphide - CH3SCH3",
4581            Self::HydrogenChloride => "Hydrogen Chloride - HCL",
4582            Self::CFC11 => "CFC-11",
4583            Self::CFC12 => "CFC-12",
4584            Self::CFC113 => "CFC-113",
4585            Self::CFC113a => "CFC-113a",
4586            Self::CFC114 => "CFC-114",
4587            Self::CFC115 => "CFC-115",
4588            Self::HCFC22 => "HCFC-22",
4589            Self::HCFC141b => "HCFC-141b",
4590            Self::HCFC142b => "HCFC-142b",
4591            Self::Halon1202 => "Halon-1202",
4592            Self::Halon1211 => "Halon-1211",
4593            Self::Halon1301 => "Halon-1301",
4594            Self::Halon2402 => "Halon-2402",
4595            Self::MethylChloride => "Methyl Chloride (HCC-40)",
4596            Self::CarbonTetrachloride => "Carbon Tetrachloride (HCC-10)",
4597            Self::HCC140a => "HCC-140a - CH3CCl3",
4598            Self::MethylBromide => "Methyl Bromide (HBC-40B1)",
4599            Self::Hexachlorocyclohexane => "Hexachlorocyclohexane (HCH)",
4600            Self::AlphaHexachlorocyclohexane => "Alpha Hexachlorocyclohexane",
4601            Self::Hexachlorobiphenyl => "Hexachlorobiphenyl (PCB-153)",
4602            Self::RadioactivePollutant => {
4603                "Radioactive Pollutant (Tracer, defined by originating centre)"
4604            }
4605            Self::HOxRadical => "HOx Radical (OH+HO2)",
4606            Self::TotalInorganicAndOrganicPeroxyRadicals => {
4607                "Total Inorganic and Organic Peroxy Radicals (HO2+RO2) - RO2"
4608            }
4609            Self::PassiveOzone => "Passive Ozone",
4610            Self::NOxExpressedAsNitrogen => "NOx Expressed As Nitrogen - NOx",
4611            Self::AllNitrogenOxides => "All Nitrogen Oxides (NOy) Expressed As Nitrogen - NOy",
4612            Self::TotalInorganicChlorineExceptHClClONO2 => {
4613                "Total Inorganic Chlorine Except HCl, ClONO2: ClOx"
4614            }
4615            Self::TotalInorganicBromineExceptHBrBrONO2 => {
4616                "Total Inorganic Bromine Except HBr, BrONO2: BrOx"
4617            }
4618            Self::LumpedAlkanes => "Lumped Alkanes",
4619            Self::LumpedAlkenes => "Lumped Alkenes",
4620            Self::LumpedAromaticCompounds => "Lumped Aromatic Compounds",
4621            Self::LumpedTerpenes => "Lumped Terpenes",
4622            Self::NonMethaneVolatileOrganicCompounds => {
4623                "Non-Methane Volatile Organic Compounds Expressed as Carbon - NMVOC"
4624            }
4625            Self::AnthropogenicNMVOCExpressedAsCarbon => {
4626                "Anthropogenic NMVOC Expressed as Carbon - aNMVOC"
4627            }
4628            Self::BiogenicNMVOCExpressedAsCarbon => "Biogenic NMVOC Expressed as Carbon - bNMVOC",
4629            Self::LumpedOxygenatedHydrocarbons => "Lumped Oxygenated Hydrocarbons - OVOC",
4630            Self::Reserved60015 => "Reserved",
4631            Self::TotalAerosol => "Total Aerosol",
4632            Self::DustDry => "Dust Dry",
4633            Self::WaterInAmbient => "Water In Ambient",
4634            Self::AmmoniumDry => "Ammonium Dry",
4635            Self::NitrateDry => "Nitrate Dry",
4636            Self::NitricAcidTrihydrate => "Nitric Acid Trihydrate",
4637            Self::SulphateDry => "Sulphate Dry",
4638            Self::MercuryDry => "Mercury Dry",
4639            Self::SeaSaltDry => "Sea Salt Dry",
4640            Self::BlackCarbonDry => "Black Carbon Dry",
4641            Self::ParticulateOrganicMatterDry => "Particulate Organic Matter Dry",
4642            Self::PrimaryParticulateOrganicMatterDry => "Primary Particulate Organic Matter Dry",
4643            Self::SecondaryParticulateOrganicMatterDry => {
4644                "Secondary Particulate Organic Matter Dry"
4645            }
4646            Self::BlackCarbonHydrophilicDry => "Black Carbon Hydrophilic Dry",
4647            Self::BlackCarbonHydrophobicDry => "Black Carbon Hydrophobic Dry",
4648            Self::ParticulateOrganicMatterHydrophilicDry => {
4649                "Particulate Organic Matter Hydrophilic Dry"
4650            }
4651            Self::ParticulateOrganicMatterHydrophobicDry => {
4652                "Particulate Organic Matter Hydrophobic Dry"
4653            }
4654            Self::NitrateHydrophilicDry => "Nitrate Hydrophilic Dry",
4655            Self::NitrateHydrophobicDry => "Nitrate Hydrophobic Dry",
4656            Self::Reserved62019 => "Reserved",
4657            Self::SmokeHighAbsorption => "Smoke - High Absorption",
4658            Self::SmokeLowAbsorption => "Smoke - Low Absorption",
4659            Self::AerosolHighAbsorption => "Aerosol - High Absorption",
4660            Self::AerosolLowAbsorption => "Aerosol - Low Absorption",
4661            Self::Reserved62024 => "Reserved",
4662            Self::VolcanicAsh => "Volcanic Ash",
4663            Self::BrownCarbonDry => "Brown Carbon Dry",
4664            Self::Missing => "Missing",
4665        };
4666        f.write_str(desc)
4667    }
4668}
4669
4670/// GRIB2 - CODE TABLE 4.234: CANOPY COVER FRACTION
4671///
4672/// **Created**: 07/12/2013
4673///
4674/// **Description**:
4675/// To be used as partitioned parameter in Product Definition Templates (PDT) 4.53 or 4.54.
4676///
4677/// ## Links
4678/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-234.shtml)
4679#[repr(u8)]
4680#[allow(missing_docs)]
4681#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4682pub enum Grib2Table4_234 {
4683    CropsMixedFarming = 1,
4684    ShortGrass = 2,
4685    EvergreenNeedleleafTrees = 3,
4686    DeciduousNeedleleafTrees = 4,
4687    DeciduousBroadleafTrees = 5,
4688    EvergreenBroadleafTrees = 6,
4689    TallGrass = 7,
4690    Desert = 8,
4691    Tundra = 9,
4692    IrrigatedCrops = 10,
4693    Semidesert = 11,
4694    IceCapsAndGlaciers = 12,
4695    BogsAndMarshes = 13,
4696    InlandWater = 14,
4697    Ocean = 15,
4698    EvergreenShrubs = 16,
4699    DeciduousShrubs = 17,
4700    MixedForest = 18,
4701    InterruptedForest = 19,
4702    WaterAndLandMixtures = 20,
4703    Missing = 255,
4704}
4705impl From<u8> for Grib2Table4_234 {
4706    fn from(val: u8) -> Self {
4707        match val {
4708            1 => Self::CropsMixedFarming,
4709            2 => Self::ShortGrass,
4710            3 => Self::EvergreenNeedleleafTrees,
4711            4 => Self::DeciduousNeedleleafTrees,
4712            5 => Self::DeciduousBroadleafTrees,
4713            6 => Self::EvergreenBroadleafTrees,
4714            7 => Self::TallGrass,
4715            8 => Self::Desert,
4716            9 => Self::Tundra,
4717            10 => Self::IrrigatedCrops,
4718            11 => Self::Semidesert,
4719            12 => Self::IceCapsAndGlaciers,
4720            13 => Self::BogsAndMarshes,
4721            14 => Self::InlandWater,
4722            15 => Self::Ocean,
4723            16 => Self::EvergreenShrubs,
4724            17 => Self::DeciduousShrubs,
4725            18 => Self::MixedForest,
4726            19 => Self::InterruptedForest,
4727            20 => Self::WaterAndLandMixtures,
4728            _ => Self::Missing,
4729        }
4730    }
4731}
4732impl core::fmt::Display for Grib2Table4_234 {
4733    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4734        let desc = match self {
4735            Self::CropsMixedFarming => "Crops, mixed farming",
4736            Self::ShortGrass => "Short grass",
4737            Self::EvergreenNeedleleafTrees => "Evergreen needleleaf trees",
4738            Self::DeciduousNeedleleafTrees => "Deciduous needleleaf trees",
4739            Self::DeciduousBroadleafTrees => "Deciduous broadleaf trees",
4740            Self::EvergreenBroadleafTrees => "Evergreen broadleaf trees",
4741            Self::TallGrass => "Tall grass",
4742            Self::Desert => "Desert",
4743            Self::Tundra => "Tundra",
4744            Self::IrrigatedCrops => "Irrigated crops",
4745            Self::Semidesert => "Semidesert",
4746            Self::IceCapsAndGlaciers => "Ice caps and glaciers",
4747            Self::BogsAndMarshes => "Bogs and marshes",
4748            Self::InlandWater => "Inland water",
4749            Self::Ocean => "Ocean",
4750            Self::EvergreenShrubs => "Evergreen shrubs",
4751            Self::DeciduousShrubs => "Deciduous shrubs",
4752            Self::MixedForest => "Mixed forest",
4753            Self::InterruptedForest => "Interrupted forest",
4754            Self::WaterAndLandMixtures => "Water and land mixtures",
4755            Self::Missing => "Missing",
4756        };
4757        f.write_str(desc)
4758    }
4759}
4760
4761/// GRIB2 - CODE TABLE 4.235: Wind-Generated Wave Spectral Description
4762///
4763/// **Created**: 02/15/2012
4764///
4765/// ## Links
4766/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-235.shtml)
4767#[repr(u8)]
4768#[allow(missing_docs)]
4769#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4770pub enum Grib2Table4_235 {
4771    TotalWaveSpectrum = 0,
4772    GeneralizedPartition = 1,
4773    Missing = 255,
4774}
4775impl From<u8> for Grib2Table4_235 {
4776    fn from(val: u8) -> Self {
4777        match val {
4778            0 => Self::TotalWaveSpectrum,
4779            1 => Self::GeneralizedPartition,
4780            _ => Self::Missing,
4781        }
4782    }
4783}
4784impl core::fmt::Display for Grib2Table4_235 {
4785    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4786        let desc = match self {
4787            Self::TotalWaveSpectrum => "Total Wave Spectrum (combined wind waves and swell)",
4788            Self::GeneralizedPartition => "Generalized Partition",
4789            Self::Missing => "Missing",
4790        };
4791        f.write_str(desc)
4792    }
4793}
4794
4795/// GRIB2 - CODE TABLE 4.236: Soil Texture Fraction
4796/// (to be used as partitioned parameter in PDT 4.53 or 4.54)
4797///
4798/// **Created**: 07/12/2013
4799///
4800/// ## Links
4801/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-236.shtml)
4802#[repr(u8)]
4803#[allow(missing_docs)]
4804#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4805pub enum Grib2Table4_236 {
4806    Coarse = 1,
4807    Medium = 2,
4808    MediumFine = 3,
4809    Fine = 4,
4810    VeryFine = 5,
4811    Organic = 6,
4812    TropicalOrganic = 7,
4813    Missing = 255,
4814}
4815impl From<u8> for Grib2Table4_236 {
4816    fn from(val: u8) -> Self {
4817        match val {
4818            1 => Self::Coarse,
4819            2 => Self::Medium,
4820            3 => Self::MediumFine,
4821            4 => Self::Fine,
4822            5 => Self::VeryFine,
4823            6 => Self::Organic,
4824            7 => Self::TropicalOrganic,
4825            _ => Self::Missing,
4826        }
4827    }
4828}
4829impl core::fmt::Display for Grib2Table4_236 {
4830    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4831        let desc = match self {
4832            Self::Coarse => "Coarse",
4833            Self::Medium => "Medium",
4834            Self::MediumFine => "Medium-fine",
4835            Self::Fine => "Fine",
4836            Self::VeryFine => "Very-fine",
4837            Self::Organic => "Organic",
4838            Self::TropicalOrganic => "Tropical-organic",
4839            Self::Missing => "Missing",
4840        };
4841        f.write_str(desc)
4842    }
4843}
4844
4845/// GRIB2 - CODE TABLE 4.238: Source or Sink
4846///
4847/// **Revised**: 07/15/2024
4848/// Red text depicts changes made since 07/15/2024
4849///
4850/// ## Links
4851/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-238.shtml)
4852#[repr(u8)]
4853#[allow(missing_docs)]
4854#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4855pub enum Grib2Table4_238 {
4856    Reserved = 0,
4857    Aviation = 1,
4858    Lightning = 2,
4859    BiogenicSources = 3,
4860    AnthropogenicSources = 4,
4861    WildFires = 5,
4862    NaturalSources = 6,
4863    BioFuel = 7,
4864    Volcanoes = 8,
4865    FossilFuel = 9,
4866    Wetlands = 10,
4867    Oceans = 11,
4868    ElevatedAnthropogenicSources = 12,
4869    SurfaceAnthropogenicSources = 13,
4870    AgricultureLivestock = 14,
4871    AgricultureSOils = 15,
4872    AgricultureWasteBurning = 16,
4873    AgricultureAll = 17,
4874    ResidentialCommercialAndOtherCombustion = 18,
4875    PowerGeneration = 19,
4876    SuperPowerStations = 20,
4877    Fugitives = 21,
4878    IndustrialProcess = 22,
4879    Solvents = 23,
4880    Ships = 24,
4881    Wastes = 25,
4882    RoadTransportation = 26,
4883    OffRoadTransportation = 27,
4884    NuclearPowerPlant = 28,
4885    NuclearWeapon = 29,
4886    Missing = 255,
4887}
4888impl From<u8> for Grib2Table4_238 {
4889    fn from(val: u8) -> Self {
4890        match val {
4891            0 => Self::Reserved,
4892            1 => Self::Aviation,
4893            2 => Self::Lightning,
4894            3 => Self::BiogenicSources,
4895            4 => Self::AnthropogenicSources,
4896            5 => Self::WildFires,
4897            6 => Self::NaturalSources,
4898            7 => Self::BioFuel,
4899            8 => Self::Volcanoes,
4900            9 => Self::FossilFuel,
4901            10 => Self::Wetlands,
4902            11 => Self::Oceans,
4903            12 => Self::ElevatedAnthropogenicSources,
4904            13 => Self::SurfaceAnthropogenicSources,
4905            14 => Self::AgricultureLivestock,
4906            15 => Self::AgricultureSOils,
4907            16 => Self::AgricultureWasteBurning,
4908            17 => Self::AgricultureAll,
4909            18 => Self::ResidentialCommercialAndOtherCombustion,
4910            19 => Self::PowerGeneration,
4911            20 => Self::SuperPowerStations,
4912            21 => Self::Fugitives,
4913            22 => Self::IndustrialProcess,
4914            23 => Self::Solvents,
4915            24 => Self::Ships,
4916            25 => Self::Wastes,
4917            26 => Self::RoadTransportation,
4918            27 => Self::OffRoadTransportation,
4919            28 => Self::NuclearPowerPlant,
4920            29 => Self::NuclearWeapon,
4921            _ => Self::Missing,
4922        }
4923    }
4924}
4925impl core::fmt::Display for Grib2Table4_238 {
4926    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4927        let desc = match self {
4928            Self::Reserved => "Reserved",
4929            Self::Aviation => "Aviation",
4930            Self::Lightning => "Lightning",
4931            Self::BiogenicSources => "Biogenic Sources",
4932            Self::AnthropogenicSources => "Anthropogenic sources",
4933            Self::WildFires => "Wild fires",
4934            Self::NaturalSources => "Natural sources",
4935            Self::BioFuel => "Bio-fuel",
4936            Self::Volcanoes => "Volcanoes",
4937            Self::FossilFuel => "Fossil-fuel",
4938            Self::Wetlands => "Wetlands",
4939            Self::Oceans => "Oceans",
4940            Self::ElevatedAnthropogenicSources => "Elevated anthropogenic sources",
4941            Self::SurfaceAnthropogenicSources => "Surface anthropogenic sources",
4942            Self::AgricultureLivestock => "Agriculture livestock",
4943            Self::AgricultureSOils => "Agriculture soils",
4944            Self::AgricultureWasteBurning => "Agriculture waste burning",
4945            Self::AgricultureAll => "Agriculture (all)",
4946            Self::ResidentialCommercialAndOtherCombustion => {
4947                "Residential, commercial and other combustion"
4948            }
4949            Self::PowerGeneration => "Power generation",
4950            Self::SuperPowerStations => "Super power stations",
4951            Self::Fugitives => "Fugitives",
4952            Self::IndustrialProcess => "Industrial process",
4953            Self::Solvents => "Solvents",
4954            Self::Ships => "Ships",
4955            Self::Wastes => "Wastes",
4956            Self::RoadTransportation => "Road transportation",
4957            Self::OffRoadTransportation => "Off-road transportation",
4958            Self::NuclearPowerPlant => "Nuclear power plant",
4959            Self::NuclearWeapon => "Nuclear weapon",
4960            Self::Missing => "Missing",
4961        };
4962        f.write_str(desc)
4963    }
4964}
4965
4966/// GRIB2 - CODE TABLE 4.239: Wetland Type
4967///
4968/// **Created**: 10/24/2023
4969///
4970/// ## Links
4971/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-239.shtml)
4972#[repr(u8)]
4973#[allow(missing_docs)]
4974#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4975pub enum Grib2Table4_239 {
4976    Reserved = 0,
4977    Bog = 1,
4978    Drained = 2,
4979    Fen = 3,
4980    Floodplain = 4,
4981    Mangrove = 5,
4982    Marsh = 6,
4983    Rice = 7,
4984    Riverine = 8,
4985    SaltMarsh = 9,
4986    Swamp = 10,
4987    Upland = 11,
4988    WetTundra = 12,
4989    Missing = 255,
4990}
4991impl From<u8> for Grib2Table4_239 {
4992    fn from(val: u8) -> Self {
4993        match val {
4994            0 => Self::Reserved,
4995            1 => Self::Bog,
4996            2 => Self::Drained,
4997            3 => Self::Fen,
4998            4 => Self::Floodplain,
4999            5 => Self::Mangrove,
5000            6 => Self::Marsh,
5001            7 => Self::Rice,
5002            8 => Self::Riverine,
5003            9 => Self::SaltMarsh,
5004            10 => Self::Swamp,
5005            11 => Self::Upland,
5006            12 => Self::WetTundra,
5007            _ => Self::Missing,
5008        }
5009    }
5010}
5011impl core::fmt::Display for Grib2Table4_239 {
5012    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5013        let desc = match self {
5014            Self::Reserved => "Reserved",
5015            Self::Bog => "Bog",
5016            Self::Drained => "Drained",
5017            Self::Fen => "Fen",
5018            Self::Floodplain => "Floodplain",
5019            Self::Mangrove => "Mangrove",
5020            Self::Marsh => "Marsh",
5021            Self::Rice => "Rice",
5022            Self::Riverine => "Riverine",
5023            Self::SaltMarsh => "Salt Marsh",
5024            Self::Swamp => "Swamp",
5025            Self::Upland => "Upland",
5026            Self::WetTundra => "Wet tundra",
5027            Self::Missing => "Missing",
5028        };
5029        f.write_str(desc)
5030    }
5031}
5032
5033/// GRIB2 - CODE TABLE 4.240: Type of Distribution Function
5034///
5035/// **Revised**: 07/07/2017
5036///
5037/// ## Notes
5038/// 1. Bin-Model or delta function with N concentration cl(r) in class (or mode) l.
5039///    Concentration-density function:
5040///    $f(r;d) = \sum_{l=1}^{N} cl(r) \delta(d-Dl)$
5041///    - N: Number of modes in the distribution
5042///    - $\delta$: Delta-Function
5043///    - d: Diameter
5044///    - Dl: Diameter of mode l(p1)
5045///
5046/// 2. Bin-Model or delta function with N concentration cl(r) in class (or mode) l.
5047///    Concentration-density function:
5048///    $f(r;m) = \sum_{l=1}^{N} cl(r) \delta(m-Ml)$
5049///    - N: Number of modes in the distribution
5050///    - $\delta$: Delta-Function
5051///    - m: Mass
5052///    - Ml: Mass of mode (p1)
5053///
5054/// 3. N-Modal concentration-density function consisting of Gaussian-functions:
5055///    $f(r;d) = \sum_{l=1}^{N} cl(r) (1 / \sqrt{2\pi\delta_l}) * e^{-((d-Dl)/\delta_l)^2}$
5056///    - N: Number of modes in the distribution
5057///    - d: Diameter
5058///    - Dl: Mean diameter of mode l(p1)
5059///    - $\delta_l$: Variance of Mode l (p2)
5060///    - cl(r): Concentration
5061///
5062/// 4. N-Modal concentration-density function consisting of Gaussian-functions:
5063///    $f(r;d) = \sum_{l=1}^{N} cl(r) (1 / \sqrt{2\pi\delta_l(r)}) * e^{-((d-Dl(r))/\delta_l(r))^2}$
5064///    - N: Fields of concentration cl(r)
5065///    - $\delta_l(r)$: Variance
5066///    - Dl(r): Mean diameter
5067///
5068/// ## Links
5069/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-240.shtml)
5070#[repr(u16)]
5071#[allow(missing_docs)]
5072#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5073pub enum Grib2Table4_240 {
5074    NoSpecificDistributionFunctionGiven = 0,
5075    DeltaFunctionsWithFixedDiameters = 1,
5076    DeltaFunctionsWithFixedMasses = 2,
5077    GaussianDistributionFixedMeanDiameterAndVariance = 3,
5078    GaussianDistributionVariableParameters = 4,
5079    LogNormalDistributionVariableParameters = 5,
5080    LogNormalDistributionFixedVariance = 6,
5081    LogNormalDistributionFixedVarianceAndParticleDensity = 7,
5082    DerivedFromDistributionType7 = 8,
5083    Missing = 65535,
5084}
5085impl From<u16> for Grib2Table4_240 {
5086    fn from(val: u16) -> Self {
5087        match val {
5088            0 => Self::NoSpecificDistributionFunctionGiven,
5089            1 => Self::DeltaFunctionsWithFixedDiameters,
5090            2 => Self::DeltaFunctionsWithFixedMasses,
5091            3 => Self::GaussianDistributionFixedMeanDiameterAndVariance,
5092            4 => Self::GaussianDistributionVariableParameters,
5093            5 => Self::LogNormalDistributionVariableParameters,
5094            6 => Self::LogNormalDistributionFixedVariance,
5095            7 => Self::LogNormalDistributionFixedVarianceAndParticleDensity,
5096            8 => Self::DerivedFromDistributionType7,
5097            _ => Self::Missing,
5098        }
5099    }
5100}
5101impl core::fmt::Display for Grib2Table4_240 {
5102    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5103        let desc = match self {
5104            Self::NoSpecificDistributionFunctionGiven => "No specific distribution function given",
5105            Self::DeltaFunctionsWithFixedDiameters => {
5106                "Delta functions with spatially variable concentration and fixed diameters Dl(p1) \
5107                 in meter"
5108            }
5109            Self::DeltaFunctionsWithFixedMasses => {
5110                "Delta functions with spatially variable concentration and fixed masses Ml(p1) in \
5111                 kg"
5112            }
5113            Self::GaussianDistributionFixedMeanDiameterAndVariance => {
5114                "Gaussian (Normal) distribution with spatially variable concentration and fixed \
5115                 mean diameter Dl(p1) and variance δ(p2)"
5116            }
5117            Self::GaussianDistributionVariableParameters => {
5118                "Gaussian (Normal) distribution with spatially variable concentration, mean \
5119                 diameter and variance"
5120            }
5121            Self::LogNormalDistributionVariableParameters => {
5122                "Log-normal distribution with spatially variable number density, mean diameter and \
5123                 variance"
5124            }
5125            Self::LogNormalDistributionFixedVariance => {
5126                "Log-normal distribution with spatially variable number density, mean diameter and \
5127                 fixed variance δ(p1)"
5128            }
5129            Self::LogNormalDistributionFixedVarianceAndParticleDensity => {
5130                "Log-normal distribution with spatially variable number density and mass density \
5131                 and fixed variance δ and fixed particle density ρ(p2)"
5132            }
5133            Self::DerivedFromDistributionType7 => {
5134                "No distribution function. The encoded variable is derived from variables \
5135                 characterized by type of distribution function of type No. 7 with fixed variance \
5136                 σ(p1) and fixed particle density ρ(p2)"
5137            }
5138            Self::Missing => "Missing",
5139        };
5140        f.write_str(desc)
5141    }
5142}
5143
5144/// GRIB2 - CODE TABLE 4.241: Coverage Attributes
5145///
5146/// **Updated**: 12/07/2023
5147///
5148/// ## Links
5149/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-241.shtml)
5150#[repr(u8)]
5151#[allow(missing_docs)]
5152#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5153pub enum Grib2Table4_241 {
5154    Undefined = 0,
5155    Unmodified = 1,
5156    SnowCovered = 2,
5157    Flooded = 3,
5158    IceCovered = 4,
5159    WithInterceptedWater = 5,
5160    WithInterceptedSnow = 6,
5161    Aggregated = 7,
5162    Missing = 255,
5163}
5164impl From<u8> for Grib2Table4_241 {
5165    fn from(val: u8) -> Self {
5166        match val {
5167            0 => Self::Undefined,
5168            1 => Self::Unmodified,
5169            2 => Self::SnowCovered,
5170            3 => Self::Flooded,
5171            4 => Self::IceCovered,
5172            5 => Self::WithInterceptedWater,
5173            6 => Self::WithInterceptedSnow,
5174            7 => Self::Aggregated,
5175            _ => Self::Missing,
5176        }
5177    }
5178}
5179impl core::fmt::Display for Grib2Table4_241 {
5180    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5181        let desc = match self {
5182            Self::Undefined => "Undefined",
5183            Self::Unmodified => "Unmodified",
5184            Self::SnowCovered => "Snow-covered",
5185            Self::Flooded => "Flooded",
5186            Self::IceCovered => "Ice Covered",
5187            Self::WithInterceptedWater => "With intercepted water",
5188            Self::WithInterceptedSnow => "With intercepted snow",
5189            Self::Aggregated => "Aggregated",
5190            Self::Missing => "Missing",
5191        };
5192        f.write_str(desc)
5193    }
5194}
5195
5196/// GRIB2 - CODE TABLE 4.242: Tile Classification
5197///
5198/// **Updated**: 12/07/2023
5199///
5200/// ## Links
5201/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-242.shtml)
5202#[repr(u8)]
5203#[allow(missing_docs)]
5204#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5205pub enum Grib2Table4_242 {
5206    Reserved = 0,
5207    LandUseClassesESAGLOBCOVERGCV2009 = 1,
5208    LandUseClassesEuropeanCommissionGLC2000 = 2,
5209    LandUseClassesECOCLIMAP = 3,
5210    LandUseClassesECOCLIMAPSG = 4,
5211    LandUseClassesUSGSEROSGLCCV20BATsClassification = 5,
5212    Missing = 255,
5213}
5214impl From<u8> for Grib2Table4_242 {
5215    fn from(val: u8) -> Self {
5216        match val {
5217            0 => Self::Reserved,
5218            1 => Self::LandUseClassesESAGLOBCOVERGCV2009,
5219            2 => Self::LandUseClassesEuropeanCommissionGLC2000,
5220            3 => Self::LandUseClassesECOCLIMAP,
5221            4 => Self::LandUseClassesECOCLIMAPSG,
5222            5 => Self::LandUseClassesUSGSEROSGLCCV20BATsClassification,
5223            _ => Self::Missing,
5224        }
5225    }
5226}
5227impl core::fmt::Display for Grib2Table4_242 {
5228    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5229        let desc = match self {
5230            Self::Reserved => "Reserved",
5231            Self::LandUseClassesESAGLOBCOVERGCV2009 => {
5232                "Land use classes according to ESA-GLOBCOVER GCV2009"
5233            }
5234            Self::LandUseClassesEuropeanCommissionGLC2000 => {
5235                "Land use classes according to European Commission-Global Land Cover Project \
5236                 GLC2000"
5237            }
5238            Self::LandUseClassesECOCLIMAP => "Land use classes according to ECOCLIMAP",
5239            Self::LandUseClassesECOCLIMAPSG => "Land use classes according to ECOCLIMAP-SG",
5240            Self::LandUseClassesUSGSEROSGLCCV20BATsClassification => {
5241                "Land use classes according to USGS EROS Global Land Cover Characterization (GLCC) \
5242                 v2.0 BATS Classification"
5243            }
5244            Self::Missing => "Missing",
5245        };
5246        f.write_str(desc)
5247    }
5248}
5249
5250/// GRIB2 - CODE TABLE 4.243: Tile Class
5251///
5252/// **Created**: 04/09/2015
5253///
5254/// ## Links
5255/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-243.shtml)
5256#[repr(u8)]
5257#[allow(missing_docs)]
5258#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5259pub enum Grib2Table4_243 {
5260    Reserved = 0,
5261    EvergreenBroadleavedForest = 1,
5262    DeciduousBroadleavedClosedForest = 2,
5263    DeciduousBroadleavedOpenForest = 3,
5264    EvergreenNeedleLeafForest = 4,
5265    DeciduousNeedleLeafForest = 5,
5266    MixedLeafTrees = 6,
5267    FreshWaterFloodedTrees = 7,
5268    SalineWaterFloodedTrees = 8,
5269    MosaicTreeNaturalVegetation = 9,
5270    BurntTreeCover = 10,
5271    EvergreenShrubsClosedOpen = 11,
5272    DeciduousShrubsClosedOpen = 12,
5273    HerbaceousVegetationClosedOpen = 13,
5274    SparseHerbaceousOrGrass = 14,
5275    FloodedShrubsOrHerbaceous = 15,
5276    CultivatedAndManagedAreas = 16,
5277    MosaicCropTreeNaturalVegetation = 17,
5278    MosaicCropShrubGrass = 18,
5279    BareAreas = 19,
5280    Water = 20,
5281    SnowAndIce = 21,
5282    ArtificialSurface = 22,
5283    Ocean = 23,
5284    IrrigatedCroplands = 24,
5285    RainFedCroplands = 25,
5286    MosaicCropland5070Vegetation2050 = 26,
5287    MosaicVegetation5070Cropland2050 = 27,
5288    ClosedBroadleavedEvergreenForest = 28,
5289    ClosedNeedleLeavedEvergreenForest = 29,
5290    OpenNeedleLeavedDeciduousForest = 30,
5291    MixedBroadleavedAndNeedleLeaveForest = 31,
5292    MosaicShrubland5070Grassland2050 = 32,
5293    MosaicGrassland5070Shrubland2050 = 33,
5294    ClosedToOpenShrubland = 34,
5295    SparseVegetation = 35,
5296    ClosedToOpenForestRegularlyFlooded = 36,
5297    ClosedForestOrShrublandPermanentlyFlooded = 37,
5298    ClosedToOpenGrasslandRegularlyFlooded = 38,
5299    Undefined = 39,
5300    Missing = 255,
5301}
5302impl From<u8> for Grib2Table4_243 {
5303    fn from(val: u8) -> Self {
5304        match val {
5305            0 => Self::Reserved,
5306            1 => Self::EvergreenBroadleavedForest,
5307            2 => Self::DeciduousBroadleavedClosedForest,
5308            3 => Self::DeciduousBroadleavedOpenForest,
5309            4 => Self::EvergreenNeedleLeafForest,
5310            5 => Self::DeciduousNeedleLeafForest,
5311            6 => Self::MixedLeafTrees,
5312            7 => Self::FreshWaterFloodedTrees,
5313            8 => Self::SalineWaterFloodedTrees,
5314            9 => Self::MosaicTreeNaturalVegetation,
5315            10 => Self::BurntTreeCover,
5316            11 => Self::EvergreenShrubsClosedOpen,
5317            12 => Self::DeciduousShrubsClosedOpen,
5318            13 => Self::HerbaceousVegetationClosedOpen,
5319            14 => Self::SparseHerbaceousOrGrass,
5320            15 => Self::FloodedShrubsOrHerbaceous,
5321            16 => Self::CultivatedAndManagedAreas,
5322            17 => Self::MosaicCropTreeNaturalVegetation,
5323            18 => Self::MosaicCropShrubGrass,
5324            19 => Self::BareAreas,
5325            20 => Self::Water,
5326            21 => Self::SnowAndIce,
5327            22 => Self::ArtificialSurface,
5328            23 => Self::Ocean,
5329            24 => Self::IrrigatedCroplands,
5330            25 => Self::RainFedCroplands,
5331            26 => Self::MosaicCropland5070Vegetation2050,
5332            27 => Self::MosaicVegetation5070Cropland2050,
5333            28 => Self::ClosedBroadleavedEvergreenForest,
5334            29 => Self::ClosedNeedleLeavedEvergreenForest,
5335            30 => Self::OpenNeedleLeavedDeciduousForest,
5336            31 => Self::MixedBroadleavedAndNeedleLeaveForest,
5337            32 => Self::MosaicShrubland5070Grassland2050,
5338            33 => Self::MosaicGrassland5070Shrubland2050,
5339            34 => Self::ClosedToOpenShrubland,
5340            35 => Self::SparseVegetation,
5341            36 => Self::ClosedToOpenForestRegularlyFlooded,
5342            37 => Self::ClosedForestOrShrublandPermanentlyFlooded,
5343            38 => Self::ClosedToOpenGrasslandRegularlyFlooded,
5344            39 => Self::Undefined,
5345            _ => Self::Missing,
5346        }
5347    }
5348}
5349impl core::fmt::Display for Grib2Table4_243 {
5350    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5351        let desc = match self {
5352            Self::Reserved => "Reserved",
5353            Self::EvergreenBroadleavedForest => "Evergreen broadleaved forest",
5354            Self::DeciduousBroadleavedClosedForest => "Deciduous broadleaved closed forest",
5355            Self::DeciduousBroadleavedOpenForest => "Deciduous broadleaved open forest",
5356            Self::EvergreenNeedleLeafForest => "Evergreen needle-leaf forest",
5357            Self::DeciduousNeedleLeafForest => "Deciduous needle-leaf forest",
5358            Self::MixedLeafTrees => "Mixed leaf trees",
5359            Self::FreshWaterFloodedTrees => "Fresh water flooded trees",
5360            Self::SalineWaterFloodedTrees => "Saline water flooded trees",
5361            Self::MosaicTreeNaturalVegetation => "Mosaic tree/natural vegetation",
5362            Self::BurntTreeCover => "Burnt tree cover",
5363            Self::EvergreenShrubsClosedOpen => "Evergreen shurbs closed-open",
5364            Self::DeciduousShrubsClosedOpen => "Deciduous shurbs closed-open",
5365            Self::HerbaceousVegetationClosedOpen => "Herbaceous vegetation closed-open",
5366            Self::SparseHerbaceousOrGrass => "Sparse herbaceous or grass",
5367            Self::FloodedShrubsOrHerbaceous => "Flooded shurbs or herbaceous",
5368            Self::CultivatedAndManagedAreas => "Cultivated and managed areas",
5369            Self::MosaicCropTreeNaturalVegetation => "Mosaic crop/tree/natural vegetation",
5370            Self::MosaicCropShrubGrass => "Mosaic crop/shrub/grass",
5371            Self::BareAreas => "Bare areas",
5372            Self::Water => "Water",
5373            Self::SnowAndIce => "Snow and ice",
5374            Self::ArtificialSurface => "Artificial surface",
5375            Self::Ocean => "Ocean",
5376            Self::IrrigatedCroplands => "Irrigated croplands",
5377            Self::RainFedCroplands => "Rain fed croplands",
5378            Self::MosaicCropland5070Vegetation2050 => {
5379                "Mosaic cropland (50-70%)-vegetation (20-50%)"
5380            }
5381            Self::MosaicVegetation5070Cropland2050 => {
5382                "Mosaic vegetation (50-70%)-cropland (20-50%)"
5383            }
5384            Self::ClosedBroadleavedEvergreenForest => "Closed broadleaved evergreen forest",
5385            Self::ClosedNeedleLeavedEvergreenForest => "Closed needle-leaved evergreen forest",
5386            Self::OpenNeedleLeavedDeciduousForest => "Open needle-leaved deciduous forest",
5387            Self::MixedBroadleavedAndNeedleLeaveForest => {
5388                "Mixed broadleaved and needle-leave forest"
5389            }
5390            Self::MosaicShrubland5070Grassland2050 => {
5391                "Mosaic shrubland (50-70%)-grassland (20-50%)"
5392            }
5393            Self::MosaicGrassland5070Shrubland2050 => {
5394                "Mosaic grassland (50-70%)-shrubland (20-50%)"
5395            }
5396            Self::ClosedToOpenShrubland => "Closed to open shrubland",
5397            Self::SparseVegetation => "Sparse vegetation",
5398            Self::ClosedToOpenForestRegularlyFlooded => "Closed to open forest regularly flooded",
5399            Self::ClosedForestOrShrublandPermanentlyFlooded => {
5400                "Closed forest or shrubland permanently flooded"
5401            }
5402            Self::ClosedToOpenGrasslandRegularlyFlooded => {
5403                "Closed to open grassland regularly flooded"
5404            }
5405            Self::Undefined => "Undefined",
5406            Self::Missing => "Missing",
5407        };
5408        f.write_str(desc)
5409    }
5410}
5411
5412/// GRIB2 - CODE TABLE 4.244: QUALITY INDICATOR
5413///
5414/// **Created**: 07/09/2018
5415///
5416/// ## Links
5417/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-244.shtml)
5418#[repr(u8)]
5419#[allow(missing_docs)]
5420#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5421pub enum Grib2Table4_244 {
5422    NoQualityInformationAvailable = 0,
5423    Failed = 1,
5424    Passed = 2,
5425    Missing = 255,
5426}
5427impl From<u8> for Grib2Table4_244 {
5428    fn from(val: u8) -> Self {
5429        match val {
5430            0 => Self::NoQualityInformationAvailable,
5431            1 => Self::Failed,
5432            2 => Self::Passed,
5433            _ => Self::Missing,
5434        }
5435    }
5436}
5437impl core::fmt::Display for Grib2Table4_244 {
5438    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5439        let desc = match self {
5440            Self::NoQualityInformationAvailable => "No Quality Information Available",
5441            Self::Failed => "Failed",
5442            Self::Passed => "Passed",
5443            Self::Missing => "Missing",
5444        };
5445        f.write_str(desc)
5446    }
5447}
5448
5449/// GRIB2 - CODE TABLE 4.246: THUNDERSTORM INTENSITY INDEX
5450///
5451/// **Created**: 06/23/2022
5452///
5453/// ## Links
5454/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-246.shtml)
5455#[repr(u8)]
5456#[allow(missing_docs)]
5457#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5458pub enum Grib2Table4_246 {
5459    NoThunderstormOccurrence = 0,
5460    WeakThunderstorm = 1,
5461    ModerateThunderstorm = 2,
5462    SevereThunderstorm = 3,
5463    Missing = 255,
5464}
5465impl From<u8> for Grib2Table4_246 {
5466    fn from(val: u8) -> Self {
5467        match val {
5468            0 => Self::NoThunderstormOccurrence,
5469            1 => Self::WeakThunderstorm,
5470            2 => Self::ModerateThunderstorm,
5471            3 => Self::SevereThunderstorm,
5472            _ => Self::Missing,
5473        }
5474    }
5475}
5476impl core::fmt::Display for Grib2Table4_246 {
5477    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5478        let desc = match self {
5479            Self::NoThunderstormOccurrence => "No thunderstorm occurrence",
5480            Self::WeakThunderstorm => "Weak thunderstorm",
5481            Self::ModerateThunderstorm => "Moderate thunderstorm",
5482            Self::SevereThunderstorm => "Severe thunderstorm",
5483            Self::Missing => "Missing",
5484        };
5485        f.write_str(desc)
5486    }
5487}
5488
5489/// GRIB2 - CODE TABLE 4.247: PRECIPITATION INTENSITY
5490///
5491/// **Created**: 06/23/2022
5492///
5493/// ## Links
5494/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-247.shtml)
5495#[repr(u8)]
5496#[allow(missing_docs)]
5497#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5498pub enum Grib2Table4_247 {
5499    NoPrecipitationOccurrence = 0,
5500    LightPrecipitation = 1,
5501    ModeratePrecipitation = 2,
5502    HeavyPrecipitation = 3,
5503    Missing = 255,
5504}
5505impl From<u8> for Grib2Table4_247 {
5506    fn from(val: u8) -> Self {
5507        match val {
5508            0 => Self::NoPrecipitationOccurrence,
5509            1 => Self::LightPrecipitation,
5510            2 => Self::ModeratePrecipitation,
5511            3 => Self::HeavyPrecipitation,
5512            _ => Self::Missing,
5513        }
5514    }
5515}
5516impl core::fmt::Display for Grib2Table4_247 {
5517    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5518        let desc = match self {
5519            Self::NoPrecipitationOccurrence => "No precipitation occurrence",
5520            Self::LightPrecipitation => "Light precipitation",
5521            Self::ModeratePrecipitation => "Moderate precipitation",
5522            Self::HeavyPrecipitation => "Heavy precipitation",
5523            Self::Missing => "Missing",
5524        };
5525        f.write_str(desc)
5526    }
5527}
5528
5529/// GRIB2 - CODE TABLE 4.248: METHOD USED TO DERIVE DATA VALUE FOR A GIVEN LOCAL TIME
5530///
5531/// **Created**: 06/23/2022
5532///
5533/// ## Links
5534/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-248.shtml)
5535#[repr(u8)]
5536#[allow(missing_docs)]
5537#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5538pub enum Grib2Table4_248 {
5539    NearestForecastOrAnalysisTime = 0,
5540    InterpolatedToValidAtSpecifiedLocalTime = 1,
5541    Missing = 255,
5542}
5543impl From<u8> for Grib2Table4_248 {
5544    fn from(val: u8) -> Self {
5545        match val {
5546            0 => Self::NearestForecastOrAnalysisTime,
5547            1 => Self::InterpolatedToValidAtSpecifiedLocalTime,
5548            _ => Self::Missing,
5549        }
5550    }
5551}
5552impl core::fmt::Display for Grib2Table4_248 {
5553    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5554        let desc = match self {
5555            Self::NearestForecastOrAnalysisTime => {
5556                "Nearest forecast or analysis time to specified local time"
5557            }
5558            Self::InterpolatedToValidAtSpecifiedLocalTime => {
5559                "Interpolated to be valid at the specified local time"
5560            }
5561            Self::Missing => "Missing",
5562        };
5563        f.write_str(desc)
5564    }
5565}
5566
5567/// GRIB2 - CODE TABLE 4.249: CHARACTER OF PRECIPITATION
5568///
5569/// **Created**: 06/23/2022
5570///
5571/// ## Links
5572/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-249.shtml)
5573#[repr(u8)]
5574#[allow(missing_docs)]
5575#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5576pub enum Grib2Table4_249 {
5577    None = 0,
5578    Showers = 1,
5579    Intermittent = 2,
5580    Continuous = 3,
5581    Missing = 255,
5582}
5583impl From<u8> for Grib2Table4_249 {
5584    fn from(val: u8) -> Self {
5585        match val {
5586            0 => Self::None,
5587            1 => Self::Showers,
5588            2 => Self::Intermittent,
5589            3 => Self::Continuous,
5590            _ => Self::Missing,
5591        }
5592    }
5593}
5594impl core::fmt::Display for Grib2Table4_249 {
5595    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5596        let desc = match self {
5597            Self::None => "None",
5598            Self::Showers => "Showers",
5599            Self::Intermittent => "Intermittent",
5600            Self::Continuous => "Continuous",
5601            Self::Missing => "Missing",
5602        };
5603        f.write_str(desc)
5604    }
5605}
5606
5607/// GRIB2 - CODE TABLE 4.250: DRAINAGE DIRECTION
5608///
5609/// **Created**: 06/23/2022
5610///
5611/// ## Links
5612/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-250.shtml)
5613#[repr(u8)]
5614#[allow(missing_docs)]
5615#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5616pub enum Grib2Table4_250 {
5617    Reserved = 0,
5618    SouthWest = 1,
5619    South = 2,
5620    SouthEast = 3,
5621    West = 4,
5622    NoDirection = 5,
5623    East = 6,
5624    NorthWest = 7,
5625    North = 8,
5626    NorthEast = 9,
5627    Missing = 255,
5628}
5629impl From<u8> for Grib2Table4_250 {
5630    fn from(val: u8) -> Self {
5631        match val {
5632            0 => Self::Reserved,
5633            1 => Self::SouthWest,
5634            2 => Self::South,
5635            3 => Self::SouthEast,
5636            4 => Self::West,
5637            5 => Self::NoDirection,
5638            6 => Self::East,
5639            7 => Self::NorthWest,
5640            8 => Self::North,
5641            9 => Self::NorthEast,
5642            _ => Self::Missing,
5643        }
5644    }
5645}
5646impl core::fmt::Display for Grib2Table4_250 {
5647    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5648        let desc = match self {
5649            Self::Reserved => "Reserved",
5650            Self::SouthWest => "South-West",
5651            Self::South => "South",
5652            Self::SouthEast => "South-East",
5653            Self::West => "West",
5654            Self::NoDirection => "No direction",
5655            Self::East => "East",
5656            Self::NorthWest => "North-West",
5657            Self::North => "North",
5658            Self::NorthEast => "North-East",
5659            Self::Missing => "Missing",
5660        };
5661        f.write_str(desc)
5662    }
5663}
5664
5665/// GRIB2 - CODE TABLE 4.251: WAVE DIRECTION AND FREQUENCY FORMULAE
5666///
5667/// **Created**: 10/24/2023
5668///
5669/// ## Links
5670/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-251.shtml)
5671///
5672/// ## Notes
5673/// (1). Geometric sequence: $x_n = x_0 * r^{(n-1)}$ with 'x_0' first parameter and 'r' second parameter.
5674/// (2). Arithmetic sequence: $a_n = a_1 + (n-1) d$ with 'a_1' first parameter and 'd' second parameter.
5675#[repr(u8)]
5676#[allow(missing_docs)]
5677#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5678pub enum Grib2Table4_251 {
5679    UndefinedSequence = 0,
5680    GeometricSequence = 1,
5681    ArithmeticSequence = 2,
5682    Missing = 255,
5683}
5684impl From<u8> for Grib2Table4_251 {
5685    fn from(val: u8) -> Self {
5686        match val {
5687            0 => Self::UndefinedSequence,
5688            1 => Self::GeometricSequence,
5689            2 => Self::ArithmeticSequence,
5690            _ => Self::Missing,
5691        }
5692    }
5693}
5694impl core::fmt::Display for Grib2Table4_251 {
5695    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5696        let desc = match self {
5697            Self::UndefinedSequence => "Undefined Sequence",
5698            Self::GeometricSequence => "Geometric sequence (see Note 1)",
5699            Self::ArithmeticSequence => "Arithmetic sequence (see Note 2)",
5700            Self::Missing => "Missing",
5701        };
5702        f.write_str(desc)
5703    }
5704}
5705
5706/// GRIB2 - CODE TABLE 4.333: Transport Dispersion Model
5707///
5708/// **Created**: 07/15/2024
5709///
5710/// ## Links
5711/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-333.shtml)
5712///
5713/// ## Notes
5714/// (No additional notes provided for this table)
5715#[repr(u8)]
5716#[allow(missing_docs)]
5717#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5718pub enum Grib2Table4_333 {
5719    Reserved = 0,
5720    DERMA = 1,
5721    EEmep = 2,
5722    FLEXPART = 3,
5723    MLDP = 4,
5724    MATCH = 5,
5725    SILAM = 6,
5726    SNAP = 7,
5727    WrfChem = 8,
5728    Trajectoire = 9,
5729    Missing = 255,
5730}
5731impl From<u8> for Grib2Table4_333 {
5732    fn from(val: u8) -> Self {
5733        match val {
5734            0 => Self::Reserved,
5735            1 => Self::DERMA,
5736            2 => Self::EEmep,
5737            3 => Self::FLEXPART,
5738            4 => Self::MLDP,
5739            5 => Self::MATCH,
5740            6 => Self::SILAM,
5741            7 => Self::SNAP,
5742            8 => Self::WrfChem,
5743            9 => Self::Trajectoire,
5744            _ => Self::Missing,
5745        }
5746    }
5747}
5748impl core::fmt::Display for Grib2Table4_333 {
5749    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5750        let desc = match self {
5751            Self::Reserved => "Reserved",
5752            Self::DERMA => "DERMA (Danish Emergency Response Model of the Atmosphere)",
5753            Self::EEmep => "E-EMEP (Emergency EMEP model)",
5754            Self::FLEXPART => "FLEXPART (Particle dispersion model)",
5755            Self::MLDP => "MLDP (Modèle lagrangien de dispersion de particules)",
5756            Self::MATCH => "MATCH (Multi-scale Atmospheric Transport Model)",
5757            Self::SILAM => "SILAM (System for Integrated modeLling of Atmospheric composition)",
5758            Self::SNAP => "SNAP (Severe Nuclear Accident Program)",
5759            Self::WrfChem => "WRF-Chem (Weather Research and Forecasting Chemical model)",
5760            Self::Trajectoire => "Trajectoire (Trajectory model)",
5761            Self::Missing => "Missing",
5762        };
5763        f.write_str(desc)
5764    }
5765}
5766
5767/// GRIB2 - CODE TABLE 4.335: Emission Scenario Origin
5768///
5769/// **Created**: 07/15/2024
5770///
5771/// ## Links
5772/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-335.shtml)
5773///
5774/// ## Notes
5775/// (No additional notes provided for this table)
5776#[repr(u8)]
5777#[allow(missing_docs)]
5778#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5779pub enum Grib2Table4_335 {
5780    Reserved = 0,
5781    ARGOS = 1,
5782    JRODOS = 2,
5783    Assimilated = 3,
5784    Center = 4,
5785    Missing = 255,
5786}
5787impl From<u8> for Grib2Table4_335 {
5788    fn from(val: u8) -> Self {
5789        match val {
5790            0 => Self::Reserved,
5791            1 => Self::ARGOS,
5792            2 => Self::JRODOS,
5793            3 => Self::Assimilated,
5794            4 => Self::Center,
5795            _ => Self::Missing,
5796        }
5797    }
5798}
5799impl core::fmt::Display for Grib2Table4_335 {
5800    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5801        let desc = match self {
5802            Self::Reserved => "Reserved",
5803            Self::ARGOS => "ARGOS (Accident Reporting and Guiding Operational System)",
5804            Self::JRODOS => "JRODOS (Java version of Real time Online Decision SuppOrt System)",
5805            Self::Assimilated => "Assimilated (Scenario retrieved from measurements)",
5806            Self::Center => "Center (scenario by originating center)",
5807            Self::Missing => "Missing",
5808        };
5809        f.write_str(desc)
5810    }
5811}
5812
5813/// GRIB2 - CODE TABLE 4.336: NWP Model
5814///
5815/// **Created**: 07/15/2024
5816///
5817/// ## Links
5818/// - [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-336.shtml)
5819///
5820/// ## Notes
5821/// (No additional notes provided for this table)
5822#[repr(u8)]
5823#[allow(missing_docs)]
5824#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5825pub enum Grib2Table4_336 {
5826    Reserved = 0,
5827    AROME = 1,
5828    ARPEGE = 2,
5829    GFS = 3,
5830    HARMONIE = 4,
5831    HIRLAM = 5,
5832    IFS = 6,
5833    GEMGDPS = 7,
5834    GEMRDPS = 8,
5835    GEMHRDPS = 9,
5836    WRF = 10,
5837    Missing = 255,
5838}
5839impl From<u8> for Grib2Table4_336 {
5840    fn from(val: u8) -> Self {
5841        match val {
5842            0 => Self::Reserved,
5843            1 => Self::AROME,
5844            2 => Self::ARPEGE,
5845            3 => Self::GFS,
5846            4 => Self::HARMONIE,
5847            5 => Self::HIRLAM,
5848            6 => Self::IFS,
5849            7 => Self::GEMGDPS,
5850            8 => Self::GEMRDPS,
5851            9 => Self::GEMHRDPS,
5852            10 => Self::WRF,
5853            _ => Self::Missing,
5854        }
5855    }
5856}
5857impl core::fmt::Display for Grib2Table4_336 {
5858    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5859        let desc = match self {
5860            Self::Reserved => "Reserved",
5861            Self::AROME => "AROME (Meso scale NWP, Meteo-France)",
5862            Self::ARPEGE => "ARPEGE (Global scale NWP, Meteo-France)",
5863            Self::GFS => "GFS (Global forecast system, NCEP)",
5864            Self::HARMONIE => "HARMONIE (HIRLAM-ALADIN Research on Mesoscale Operational NWP)",
5865            Self::HIRLAM => "HIRLAM (HIgh resolution Limited Area Model)",
5866            Self::IFS => "IFS (Integrated Forecast System)",
5867            Self::GEMGDPS => "GEM GDPS (Canadian Global Deterministic Prediction System)",
5868            Self::GEMRDPS => "GEM RDPS (Canadian Regional Deterministic Prediction System)",
5869            Self::GEMHRDPS => {
5870                "GEM HRDPS (Canadian High Resolution Deterministic Prediction System)"
5871            }
5872            Self::WRF => "WRF (Weather Research and Forecasting)",
5873            Self::Missing => "Missing",
5874        };
5875        f.write_str(desc)
5876    }
5877}