use bacnet_types::enums::PropertyIdentifier as P;
use bacnet_types::error::Error;
use bacnet_types::primitives::PropertyValue;
use crate::common;
pub const DEFAULT_COV_RESUBSCRIPTION_INTERVAL: u32 = 3_600;
#[derive(Debug, Clone, Copy, PartialEq)]
pub(super) struct CovSettings {
client_cov_increment: Option<f32>,
resubscription_interval: u32,
}
impl Default for CovSettings {
fn default() -> Self {
Self {
client_cov_increment: None,
resubscription_interval: DEFAULT_COV_RESUBSCRIPTION_INTERVAL,
}
}
}
impl CovSettings {
pub(super) fn read(&self, property: P) -> Option<PropertyValue> {
Some(match property {
P::CLIENT_COV_INCREMENT => self
.client_cov_increment
.map_or(PropertyValue::Null, PropertyValue::Real),
P::COV_RESUBSCRIPTION_INTERVAL => {
PropertyValue::Unsigned(self.resubscription_interval.into())
}
_ => return None,
})
}
pub(super) fn write(
&mut self,
property: P,
value: &PropertyValue,
) -> Option<Result<(), Error>> {
Some(match (property, value) {
(P::CLIENT_COV_INCREMENT, PropertyValue::Null) => {
self.client_cov_increment = None;
Ok(())
}
(P::CLIENT_COV_INCREMENT, PropertyValue::Real(increment)) => {
self.set_client_cov_increment(Some(*increment))
}
(P::COV_RESUBSCRIPTION_INTERVAL, PropertyValue::Unsigned(raw)) => {
common::u64_to_u32(*raw)
.and_then(|seconds| self.set_resubscription_interval(seconds))
}
(P::CLIENT_COV_INCREMENT | P::COV_RESUBSCRIPTION_INTERVAL, _) => {
Err(common::invalid_data_type_error())
}
_ => return None,
})
}
pub(super) fn set_client_cov_increment(&mut self, increment: Option<f32>) -> Result<(), Error> {
if increment.is_some_and(|increment| !increment.is_finite() || increment < 0.0) {
return Err(common::value_out_of_range_error());
}
self.client_cov_increment = increment;
Ok(())
}
pub(super) fn set_resubscription_interval(&mut self, seconds: u32) -> Result<(), Error> {
if seconds == 0 {
return Err(common::value_out_of_range_error());
}
self.resubscription_interval = seconds;
Ok(())
}
}