pub mod comfort_level;
pub mod history;
pub mod readings;
pub mod temperature_unit;
pub mod time;
use std::time::SystemTime;
use thiserror::Error;
const TEMPERATURE_MAX: f32 = i16::MAX as f32 * 0.01;
const TEMPERATURE_MIN: f32 = i16::MIN as f32 * 0.01;
#[derive(Clone, Debug, Error, Eq, PartialEq)]
pub enum DecodeError {
#[error("Wrong length {length}, expected {expected_length}")]
WrongLength {
length: usize,
expected_length: usize,
},
#[error("{0}")]
InvalidValue(String),
}
#[derive(Clone, Debug, Error)]
pub enum EncodeError {
#[error("Temperature {0} out of range.")]
TemperatureOutOfRange(f32),
#[error("Time {0:?} out of range.")]
TimeOutOfRange(SystemTime),
}
fn decode_temperature(bytes: [u8; 2]) -> f32 {
i16::from_le_bytes(bytes) as f32 / 100.0
}
fn encode_temperature(temperature: f32) -> Result<[u8; 2], EncodeError> {
if !(TEMPERATURE_MIN..=TEMPERATURE_MAX).contains(&temperature) {
return Err(EncodeError::TemperatureOutOfRange(temperature));
}
let temperature_fixed = (temperature * 100.0) as i16;
Ok(temperature_fixed.to_le_bytes())
}
fn check_length(length: usize, expected_length: usize) -> Result<(), DecodeError> {
if length != expected_length {
Err(DecodeError::WrongLength {
length,
expected_length,
})
} else {
Ok(())
}
}