scd30_interface/data/
measurement_interval.rsuse byteorder::{BigEndian, ByteOrder};
use crate::{error::DataError, util::check_deserialization};
#[derive(Debug, PartialEq)]
pub struct MeasurementInterval(u16);
const MIN_MEASUREMENT_INTERVAL: u16 = 2;
const MAX_MEASUREMENT_INTERVAL: u16 = 1800;
const MEASUREMENT_INTERVAL_VAL: &str = "Measurement interval";
const INTERVAL_UNIT: &str = "s";
impl MeasurementInterval {
pub const fn to_be_bytes(&self) -> [u8; 2] {
self.0.to_be_bytes()
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for MeasurementInterval {
fn format(&self, f: defmt::Formatter) {
defmt::write!(f, "{}s", self.0)
}
}
impl TryFrom<u16> for MeasurementInterval {
type Error = DataError;
fn try_from(interval: u16) -> Result<Self, Self::Error> {
if !(MIN_MEASUREMENT_INTERVAL..=MAX_MEASUREMENT_INTERVAL).contains(&interval) {
Err(DataError::ValueOutOfRange {
parameter: MEASUREMENT_INTERVAL_VAL,
min: MIN_MEASUREMENT_INTERVAL,
max: MAX_MEASUREMENT_INTERVAL,
unit: INTERVAL_UNIT,
})
} else {
Ok(Self(interval))
}
}
}
impl TryFrom<&[u8]> for MeasurementInterval {
type Error = DataError;
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
check_deserialization(data, 3)?;
Ok(Self(BigEndian::read_u16(&data[..2])))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn deserialize_sample_works() {
let data = [0x00, 0x02, 0xE3];
let interval = MeasurementInterval::try_from(&data[..]).unwrap();
assert_eq!(interval, MeasurementInterval(2));
}
#[test]
fn serialize_sample_works() {
let interval = MeasurementInterval(2);
assert_eq!(interval.to_be_bytes(), [0x00, 0x02]);
}
#[test]
fn create_allowed_value_from_u16_works() {
let values = [2, 901, 1800];
for value in values {
assert_eq!(
MeasurementInterval::try_from(value).unwrap(),
MeasurementInterval(value)
);
}
}
#[test]
fn create_from_u16_non_null_out_of_spec_value_errors() {
let values = [1, 2000];
for value in values {
assert_eq!(
MeasurementInterval::try_from(value).unwrap_err(),
DataError::ValueOutOfRange {
parameter: MEASUREMENT_INTERVAL_VAL,
min: 2,
max: 1800,
unit: INTERVAL_UNIT
}
);
}
}
}