bacnet_objects/access_control/
point_event_batch.rs1use super::*;
4use crate::access_control::point_event_time::{next_event_time_from_frame, stamped_time_advances};
5use crate::clock::ClockFrame;
6
7pub struct CommittedAccessEvent {
12 pub report: AccessEventReport,
15 pub snapshot: Box<dyn BACnetObject>,
17 pub clock_frame: Option<ClockFrame>,
20}
21
22impl AccessPointObject {
23 pub(super) fn record_event_batch(
24 &mut self,
25 reports: &[AccessEventReport],
26 ) -> Result<Vec<CommittedAccessEvent>, Error> {
27 if self.out_of_service || self.reliability != Reliability::NO_FAULT_DETECTED {
28 return Err(common::write_access_denied_error());
29 }
30 if reports.len() > 4 {
31 return Err(common::value_out_of_range_error());
32 }
33 let mut staged = self.clone();
34 let mut stamps = vec![self.access_event_time.clone()];
35 let mut committed = Vec::with_capacity(reports.len());
36 for input in reports {
37 let mut report = input.clone();
38 let frame = staged
39 .clock
40 .as_deref()
41 .and_then(ClockReader::read_clock)
42 .filter(|frame| frame.is_valid_actual_datetime());
43 if report.time.is_none() {
44 let next = next_event_time_from_frame(frame, &staged.access_event_time);
45 if !stamped_time_advances(&staged.access_event_time, &next) {
46 return Err(common::value_out_of_range_error());
47 }
48 report.time = Some(next);
49 }
50 staged.set_access_event(report.clone())?;
53 if stamps.contains(&staged.access_event_time) {
54 return Err(common::value_out_of_range_error());
55 }
56 stamps.push(staged.access_event_time.clone());
57 committed.push(CommittedAccessEvent {
58 report,
59 snapshot: Box::new(staged.clone()),
60 clock_frame: frame,
61 });
62 }
63 *self = staged;
64 Ok(committed)
65 }
66}