Skip to main content

grib/
value.rs

1/// Missing values defined in the GRIB2 regulation.
2///
3/// Regulation 92.1.4 states as follows:
4///
5/// > All bits set to "1" for any value indicates that value is missing. This
6/// > rule shall not apply to packed data.
7///
8/// # Examples
9///
10/// ```
11/// use grib::{MissingValue, TryFromSlice};
12///
13/// let missing = i32::missing();
14/// let read_from_slice =
15///     i32::try_from_slice(&[0xff, 0xff, 0xff, 0xff].as_slice(), &mut 0).unwrap();
16/// assert_eq!(missing, read_from_slice);
17/// assert!(missing.is_missing());
18/// ```
19pub trait MissingValue {
20    /// Returns missing value.
21    fn missing() -> Self;
22
23    /// Checks if the value is regarded as a missing value.
24    fn is_missing(&self) -> bool;
25}
26
27macro_rules! add_missing_value_impl_for_unsigned_integer_types {
28    ($($ty:ty,)*) => ($(
29        impl MissingValue for $ty {
30            fn missing() -> Self {
31                Self::MAX
32            }
33
34            fn is_missing(&self) -> bool {
35                *self == Self::MAX
36            }
37        }
38    )*);
39}
40
41add_missing_value_impl_for_unsigned_integer_types![u8, u16, u32, u64,];
42
43macro_rules! add_missing_value_impl_for_signed_integer_types {
44    ($($ty:ty,)*) => ($(
45        impl MissingValue for $ty {
46            fn missing() -> Self {
47                Self::MIN + 1
48            }
49
50            fn is_missing(&self) -> bool {
51                *self == Self::MIN + 1
52            }
53        }
54    )*);
55}
56
57add_missing_value_impl_for_signed_integer_types![i8, i16, i32, i64,];
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use crate::TryFromSlice as _;
63
64    macro_rules! test_missing_values {
65        ($(($name:ident, $ty:ty),)*) => ($(
66            #[test]
67            fn $name() -> Result<(), Box<dyn std::error::Error>> {
68                let expected = [0xff_u8; (<$ty>::BITS / 8) as usize];
69                let expected = <$ty>::try_from_slice(expected.as_slice(), &mut 0)?;
70                let actual = <$ty>::missing();
71                assert_eq!(actual, expected);
72                assert!(actual.is_missing());
73                Ok(())
74            }
75        )*);
76    }
77
78    test_missing_values! {
79        (missing_value_for_u8, u8),
80        (missing_value_for_u16, u16),
81        (missing_value_for_u32, u32),
82        (missing_value_for_u64, u64),
83        (missing_value_for_i8, i8),
84        (missing_value_for_i16, i16),
85        (missing_value_for_i32, i32),
86        (missing_value_for_i64, i64),
87    }
88}