Skip to main content

matter_clusters/
types.rs

1//! Hand-written support types referenced by generated cluster code.
2
3/// A value that may be explicitly null on the wire (Matter quality `X`).
4///
5/// Distinct from [`Option`]: `Option<T>` models an **optional** element
6/// (its tag is absent entirely), whereas `Nullable<T>` models a **present**
7/// element whose TLV value is the null type. A field that is both optional
8/// and nullable is `Option<Nullable<T>>`.
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub enum Nullable<T> {
11    /// The wire carried an explicit TLV null.
12    Null,
13    /// The wire carried a concrete value.
14    Value(T),
15}
16
17impl<T> Nullable<T> {
18    /// Returns the contained value, or `None` if null.
19    pub fn value(self) -> Option<T> {
20        match self {
21            Nullable::Null => None,
22            Nullable::Value(v) => Some(v),
23        }
24    }
25
26    /// Returns `true` if this is [`Nullable::Null`].
27    #[must_use]
28    pub fn is_null(&self) -> bool {
29        matches!(self, Nullable::Null)
30    }
31}
32
33impl<T> From<Option<T>> for Nullable<T> {
34    fn from(o: Option<T>) -> Self {
35        match o {
36            Some(v) => Nullable::Value(v),
37            None => Nullable::Null,
38        }
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn value_and_is_null() {
48        assert_eq!(Nullable::Value(7u8).value(), Some(7));
49        assert!(Nullable::<u8>::Null.value().is_none());
50        assert!(Nullable::<u8>::Null.is_null());
51        assert!(!Nullable::Value(7u8).is_null());
52    }
53
54    #[test]
55    fn from_option() {
56        assert_eq!(Nullable::from(Some(3u8)), Nullable::Value(3));
57        assert_eq!(Nullable::<u8>::from(None), Nullable::Null);
58    }
59}