use super::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GetEventInformationBudget {
pub max_objects: usize,
pub max_returned_summaries: usize,
pub max_service_ack_bytes: usize,
}
impl Default for GetEventInformationBudget {
fn default() -> Self {
Self {
max_objects: 4096,
max_returned_summaries: 256,
max_service_ack_bytes: 16384,
}
}
}
impl GetEventInformationBudget {
pub fn validate(&self) -> Result<(), Error> {
for (name, value) in [
("event_information_max_objects", self.max_objects),
(
"event_information_max_returned_summaries",
self.max_returned_summaries,
),
(
"event_information_max_service_ack_bytes",
self.max_service_ack_bytes,
),
] {
if value == 0 {
return Err(Error::Encoding(format!("{name} must be positive")));
}
}
Ok(())
}
}
impl<T: TransportPort + 'static> ServerBuilder<T> {
pub fn get_event_information_budget(mut self, budget: GetEventInformationBudget) -> Self {
self.config.get_event_information_budget = budget;
self
}
}
impl BipServerBuilder {
pub fn get_event_information_budget(mut self, budget: GetEventInformationBudget) -> Self {
self.config.get_event_information_budget = budget;
self
}
}
#[cfg(feature = "sc-tls")]
impl ScServerBuilder {
pub fn get_event_information_budget(mut self, budget: GetEventInformationBudget) -> Self {
self.config.get_event_information_budget = budget;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::server::test_transport::TestTransport;
#[tokio::test]
async fn get_event_information_all_builders_validate_before_start_or_dial() {
let default = GetEventInformationBudget::default();
assert_eq!(
(
default.max_objects,
default.max_returned_summaries,
default.max_service_ack_bytes
),
(4096, 256, 16384)
);
assert_eq!(
ServerConfig::default().get_event_information_budget,
default
);
assert!(format!("{:?}", ServerConfig::default()).contains("get_event_information_budget"));
GetEventInformationBudget {
max_objects: usize::MAX,
max_returned_summaries: usize::MAX,
max_service_ack_bytes: usize::MAX,
}
.validate()
.unwrap();
for budget in [
GetEventInformationBudget {
max_objects: 0,
..default
},
GetEventInformationBudget {
max_returned_summaries: 0,
..default
},
GetEventInformationBudget {
max_service_ack_bytes: 0,
..default
},
] {
let direct = BACnetServer::start(
ServerConfig {
get_event_information_budget: budget,
..Default::default()
},
ObjectDatabase::new(),
TestTransport::never_start(),
)
.await
.err();
let generic = BACnetServer::generic_builder()
.transport(TestTransport::never_start())
.get_event_information_budget(budget)
.build()
.await
.err();
let bip = BACnetServer::bip_builder()
.port(0)
.get_event_information_budget(budget)
.build()
.await
.err();
for error in [direct, generic, bip] {
assert!(
matches!(error, Some(Error::Encoding(m)) if m.contains("event_information_max_"))
);
}
#[cfg(feature = "sc-tls")]
{
let error = BACnetServer::sc_builder()
.hub_url("not-a-websocket-url")
.tls_config(crate::server::sc_builder::test_tls_config())
.device_uuid(crate::server::sc_builder::TEST_DEVICE_UUID)
.get_event_information_budget(budget)
.build()
.await
.err();
assert!(
matches!(error, Some(Error::Encoding(m)) if m.contains("event_information_max_"))
);
}
}
}
}