#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use bacnet_types::constructed::{BACnetLandingCallStatus, LandingCallCommand};
use bacnet_types::enums::LiftCarDirection;
use bacnet_types::error::Error;
use bytes::BytesMut;
use super::members::{narrow, unsigned_member};
use super::tagged::{
contents, decode_ctx_character_string, decode_ctx_primitive, decode_optional_ctx,
};
use crate::primitives;
use crate::tags;
pub fn encode_landing_call_status(
buf: &mut BytesMut,
value: &BACnetLandingCallStatus,
) -> Result<(), Error> {
let mut encoded = BytesMut::new();
primitives::encode_ctx_unsigned(&mut encoded, 0, value.floor_number.into());
match value.command {
LandingCallCommand::Direction(direction) => {
primitives::encode_ctx_enumerated(&mut encoded, 1, direction.to_raw())
}
LandingCallCommand::Destination(floor) => {
primitives::encode_ctx_unsigned(&mut encoded, 2, floor.into())
}
}
if let Some(text) = &value.floor_text {
primitives::encode_ctx_character_string(&mut encoded, 3, text)?;
}
buf.extend_from_slice(&encoded);
Ok(())
}
pub fn encode_landing_call_status_list(
buf: &mut BytesMut,
values: &[BACnetLandingCallStatus],
) -> Result<(), Error> {
let mut encoded = BytesMut::new();
for value in values {
encode_landing_call_status(&mut encoded, value)?;
}
buf.extend_from_slice(&encoded);
Ok(())
}
pub fn decode_landing_call_status(
data: &[u8],
offset: usize,
) -> Result<(BACnetLandingCallStatus, usize), Error> {
let mut oversized = None;
let (floor, offset) =
decode_ctx_primitive(data, offset, 0, "landing call status floor-number")?;
let floor_number = narrow(
unsigned_member(floor, offset - floor.len())?,
"floor-number [0] exceeds an Unsigned8",
&mut oversized,
);
let (tag, content) = tags::decode_tag(data, offset)?;
let (command, offset) = if tag.is_context(1) {
let (raw, end) = contents(data, content, tag.length)?;
let direction: u32 = narrow(
unsigned_member(raw, content)?,
"direction [1] exceeds 32 bits",
&mut oversized,
);
(
LandingCallCommand::Direction(LiftCarDirection::from_raw(direction)),
end,
)
} else if tag.is_context(2) {
let (raw, end) = contents(data, content, tag.length)?;
let destination = narrow(
unsigned_member(raw, content)?,
"destination [2] exceeds an Unsigned8",
&mut oversized,
);
(LandingCallCommand::Destination(destination), end)
} else {
return Err(Error::decoding(
offset,
"landing call status requires direction [1] or destination [2]",
));
};
let (floor_text, offset) = decode_optional_ctx(
data,
offset,
3,
"landing call status floor-text",
decode_ctx_character_string,
)?;
if let Some(member) = oversized {
return Err(Error::OutOfRange(format!("landing call status {member}")));
}
Ok((
BACnetLandingCallStatus {
floor_number,
command,
floor_text,
},
offset,
))
}
pub fn decode_landing_call_status_list(data: &[u8]) -> Result<Vec<BACnetLandingCallStatus>, Error> {
let mut values = Vec::new();
let mut offset = 0;
while offset < data.len() {
let (value, end) = decode_landing_call_status(data, offset)?;
values.push(value);
offset = end;
}
Ok(values)
}