Skip to main content

bacnet_objects/audit/
reporter_configuration.rs

1//! Fallible local setters share the complete object-owned change boundary.
2use super::*;
3impl AuditReporterObject {
4    /// Set Audit_Level; live admission failure leaves all state unchanged.
5    pub fn set_audit_level(&mut self, level: AuditLevel) -> Result<(), Error> {
6        let mut next = self.configuration_internal();
7        next.audit_level = level;
8        self.change_configuration(next, None)
9    }
10    /// Set Auditable_Operations atomically with any required notification.
11    pub fn set_auditable_operations(
12        &mut self,
13        operations: AuditOperationFlags,
14    ) -> Result<(), Error> {
15        let mut next = self.configuration_internal();
16        next.auditable_operations = operations;
17        self.change_configuration(next, None)
18    }
19    /// Set the command-priority filter atomically.
20    pub fn set_audit_priority_filter(&mut self, filter: BACnetPriorityFilter) -> Result<(), Error> {
21        let mut next = self.configuration_internal();
22        next.audit_priority_filter = filter;
23        self.change_configuration(next, None)
24    }
25    /// Set confirmed delivery mode atomically.
26    pub fn set_issue_confirmed_notifications(&mut self, confirmed: bool) -> Result<(), Error> {
27        let mut next = self.configuration_internal();
28        next.confirmed = confirmed;
29        self.change_configuration(next, None)
30    }
31    /// Set optional selectors: absent means catch-all; present empty means no nominal targets.
32    pub fn set_monitored_objects(
33        &mut self,
34        selectors: Option<Vec<BACnetObjectSelector>>,
35    ) -> Result<(), Error> {
36        let mut next = self.configuration_internal();
37        next.monitored_objects = selectors;
38        self.change_configuration(next, None)
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    #[test]
46    fn audit_reporter_configuration_aba_invalidates_delivery_authority_and_failed_updates_do_not() {
47        let mut reporter = AuditReporterObject::new(1, "AR").unwrap();
48        reporter.set_audit_level(AuditLevel::AUDIT_ALL).unwrap();
49        let status = reporter.status_internal();
50        status.set_configured(true);
51        let original = status.begin_delivery();
52        assert!(
53            reporter
54                .configure_audit_reporter_internal(
55                    AuditLevel::DEFAULT,
56                    AuditOperationFlags::empty(),
57                    true,
58                    Some(vec![]),
59                    BACnetPriorityFilter::empty(),
60                    None
61                )
62                .is_err()
63        );
64        assert_eq!(
65            status.begin_delivery(),
66            original,
67            "invalid full configuration is atomic"
68        );
69        reporter.set_issue_confirmed_notifications(true).unwrap();
70        reporter.set_issue_confirmed_notifications(false).unwrap();
71        let current = status.begin_delivery();
72        assert_ne!(original, current);
73        status.complete_delivery(original, false);
74        assert_eq!(reporter.reliability(), Reliability::NO_FAULT_DETECTED);
75        status.complete_delivery(current, false);
76        status.complete_delivery(original, true);
77        assert_eq!(reporter.reliability(), Reliability::COMMUNICATION_FAILURE);
78        status.complete_delivery(status.begin_delivery(), true);
79        assert_eq!(reporter.reliability(), Reliability::NO_FAULT_DETECTED);
80    }
81}