1pub trait MissingValue {
20 fn missing() -> Self;
22
23 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}