scd30_interface/data/
measurement_interval.rs1use byteorder::{BigEndian, ByteOrder};
2
3use crate::{error::DataError, util::check_deserialization};
4
5#[derive(Debug, PartialEq)]
8pub struct MeasurementInterval(u16);
9
10const MIN_MEASUREMENT_INTERVAL: u16 = 2;
11const MAX_MEASUREMENT_INTERVAL: u16 = 1800;
12const MEASUREMENT_INTERVAL_VAL: &str = "Measurement interval";
13const INTERVAL_UNIT: &str = "s";
14
15impl MeasurementInterval {
16 pub const fn to_be_bytes(&self) -> [u8; 2] {
18 self.0.to_be_bytes()
19 }
20}
21
22#[cfg(feature = "defmt")]
23impl defmt::Format for MeasurementInterval {
24 fn format(&self, f: defmt::Formatter) {
25 defmt::write!(f, "{}s", self.0)
26 }
27}
28
29impl TryFrom<u16> for MeasurementInterval {
30 type Error = DataError;
31
32 fn try_from(interval: u16) -> Result<Self, Self::Error> {
39 if !(MIN_MEASUREMENT_INTERVAL..=MAX_MEASUREMENT_INTERVAL).contains(&interval) {
40 Err(DataError::ValueOutOfRange {
41 parameter: MEASUREMENT_INTERVAL_VAL,
42 min: MIN_MEASUREMENT_INTERVAL,
43 max: MAX_MEASUREMENT_INTERVAL,
44 unit: INTERVAL_UNIT,
45 })
46 } else {
47 Ok(Self(interval))
48 }
49 }
50}
51
52impl TryFrom<&[u8]> for MeasurementInterval {
53 type Error = DataError;
54
55 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
63 check_deserialization(data, 3)?;
64 Ok(Self(BigEndian::read_u16(&data[..2])))
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn deserialize_sample_works() {
74 let data = [0x00, 0x02, 0xE3];
75 let interval = MeasurementInterval::try_from(&data[..]).unwrap();
76 assert_eq!(interval, MeasurementInterval(2));
77 }
78
79 #[test]
80 fn serialize_sample_works() {
81 let interval = MeasurementInterval(2);
82 assert_eq!(interval.to_be_bytes(), [0x00, 0x02]);
83 }
84
85 #[test]
86 fn create_allowed_value_from_u16_works() {
87 let values = [2, 901, 1800];
88 for value in values {
89 assert_eq!(
90 MeasurementInterval::try_from(value).unwrap(),
91 MeasurementInterval(value)
92 );
93 }
94 }
95
96 #[test]
97 fn create_from_u16_non_null_out_of_spec_value_errors() {
98 let values = [1, 2000];
99 for value in values {
100 assert_eq!(
101 MeasurementInterval::try_from(value).unwrap_err(),
102 DataError::ValueOutOfRange {
103 parameter: MEASUREMENT_INTERVAL_VAL,
104 min: 2,
105 max: 1800,
106 unit: INTERVAL_UNIT
107 }
108 );
109 }
110 }
111}