bacnet_encoding/constructed/
access_rule.rs1use bacnet_types::constructed::BACnetAccessRule;
15use bacnet_types::enums::{AccessRuleLocationSpecifier, AccessRuleTimeRangeSpecifier};
16use bacnet_types::error::Error;
17use bytes::BytesMut;
18
19use super::tagged::{
20 decode_ctx_boolean, decode_ctx_unsigned, expect_closing, expect_opening, next_is_opening,
21};
22use super::{
23 decode_device_object_reference, decode_dopr_body, encode_device_object_reference,
24 encode_dopr_body,
25};
26use crate::{primitives, tags};
27
28const RULE: &str = "BACnetAccessRule";
29
30pub fn encode_access_rule(buf: &mut BytesMut, rule: &BACnetAccessRule) {
36 primitives::encode_ctx_enumerated(buf, 0, rule.time_range_specifier.to_raw());
37 if let Some(time_range) = &rule.time_range {
38 tags::encode_opening_tag(buf, 1);
39 encode_dopr_body(buf, time_range);
40 tags::encode_closing_tag(buf, 1);
41 }
42 primitives::encode_ctx_enumerated(buf, 2, rule.location_specifier.to_raw());
43 if let Some(location) = &rule.location {
44 tags::encode_opening_tag(buf, 3);
45 encode_device_object_reference(buf, location);
46 tags::encode_closing_tag(buf, 3);
47 }
48 primitives::encode_ctx_boolean(buf, 4, rule.enable);
49}
50
51pub fn decode_access_rule(data: &[u8], offset: usize) -> Result<(BACnetAccessRule, usize), Error> {
58 let (time_range_specifier, mut pos) = decode_ctx_unsigned::<u32>(data, offset, 0, RULE)?;
59 let time_range = if next_is_opening(data, pos, 1)? {
60 let content = expect_opening(data, pos, 1, RULE)?;
61 let (reference, end) = decode_dopr_body(data, content, RULE)?;
62 pos = expect_closing(data, end, 1, RULE)?;
63 Some(reference)
64 } else {
65 None
66 };
67 let (location_specifier, mut pos) = decode_ctx_unsigned::<u32>(data, pos, 2, RULE)?;
68 let location = if next_is_opening(data, pos, 3)? {
69 let content = expect_opening(data, pos, 3, RULE)?;
70 let (reference, end) = decode_device_object_reference(data, content)?;
71 pos = expect_closing(data, end, 3, RULE)?;
72 Some(reference)
73 } else {
74 None
75 };
76 let (enable, end) = decode_ctx_boolean(data, pos, 4, RULE)?;
77 Ok((
78 BACnetAccessRule {
79 time_range_specifier: AccessRuleTimeRangeSpecifier::from_raw(time_range_specifier),
80 time_range,
81 location_specifier: AccessRuleLocationSpecifier::from_raw(location_specifier),
82 location,
83 enable,
84 },
85 end,
86 ))
87}