use bacnet_types::constructed::BACnetObjectPropertyReference;
use bacnet_types::error::Error;
use bytes::BytesMut;
use crate::primitives;
use crate::tags;
use super::decode_dopr_body;
const WHAT: &str = "BACnetObjectPropertyReference";
pub fn encode_object_property_reference(buf: &mut BytesMut, r: &BACnetObjectPropertyReference) {
primitives::encode_ctx_object_id(buf, 0, &r.object_identifier);
primitives::encode_ctx_unsigned(buf, 1, r.property_identifier as u64);
if let Some(index) = r.property_array_index {
primitives::encode_ctx_unsigned(buf, 2, index as u64);
}
}
pub fn encode_setpoint_reference(buf: &mut BytesMut, r: &BACnetObjectPropertyReference) {
tags::encode_opening_tag(buf, 0);
encode_object_property_reference(buf, r);
tags::encode_closing_tag(buf, 0);
}
pub fn decode_object_property_reference(
data: &[u8],
) -> Result<BACnetObjectPropertyReference, Error> {
let (dopr, end) = decode_dopr_body(data, 0, WHAT)?;
if end != data.len() {
return Err(Error::decoding(
end,
format!("{WHAT}: trailing content after the reference members"),
));
}
if dopr.device_identifier.is_some() {
return Err(Error::decoding(
0,
format!("{WHAT}: [3] device-identifier is not part of this production"),
));
}
Ok(BACnetObjectPropertyReference {
object_identifier: dopr.object_identifier,
property_identifier: dopr.property_identifier,
property_array_index: dopr.property_array_index,
})
}
pub fn decode_setpoint_reference(
data: &[u8],
) -> Result<Option<BACnetObjectPropertyReference>, Error> {
let what = "BACnetSetpointReference";
let (tag, pos) = tags::decode_tag(data, 0)?;
if !tag.is_opening_tag(0) {
return Err(Error::decoding(
0,
format!("{what}: expected opening tag [0]"),
));
}
let (inner, after) = tags::extract_context_value(data, pos, 0)?;
if after != data.len() {
return Err(Error::decoding(
after,
format!("{what}: trailing content after the closing tag"),
));
}
if inner.is_empty() {
return Ok(None); }
decode_object_property_reference(inner).map(Some)
}
#[cfg(test)]
mod tests;