use bacnet_encoding::constructed::{decode_landing_call_status, encode_landing_call_status};
use bacnet_types::constructed::{BACnetLandingCallStatus, LandingCallCommand};
use bacnet_types::enums::LiftCarDirection;
use bacnet_types::error::Error;
use bacnet_types::primitives::PropertyValue;
use bytes::BytesMut;
use crate::common;
pub(super) fn initial_landing_call_control() -> BACnetLandingCallStatus {
BACnetLandingCallStatus {
floor_number: 0,
command: LandingCallCommand::Direction(LiftCarDirection::UNKNOWN),
floor_text: None,
}
}
pub(super) fn encode(value: &BACnetLandingCallStatus) -> Result<PropertyValue, Error> {
let mut encoded = BytesMut::new();
encode_landing_call_status(&mut encoded, value)?;
Ok(PropertyValue::ApplicationData(encoded.to_vec()))
}
pub(super) fn decode_write(value: PropertyValue) -> Result<BACnetLandingCallStatus, Error> {
let bytes = match value {
PropertyValue::ApplicationData(bytes) => bytes,
PropertyValue::List(members) if !members.is_empty() => {
let mut bytes = Vec::new();
for member in members {
let PropertyValue::ApplicationData(member) = member else {
return Err(common::invalid_data_type_error());
};
bytes.extend_from_slice(&member);
}
bytes
}
_ => return Err(common::invalid_data_type_error()),
};
let (status, consumed) =
decode_landing_call_status(&bytes, 0).map_err(|error| match error {
Error::OutOfRange(_) => common::value_out_of_range_error(),
_ => common::invalid_data_encoding_error(),
})?;
if consumed != bytes.len() {
return Err(common::invalid_data_encoding_error());
}
validate(&status)?;
Ok(status)
}
pub(super) fn validate(status: &BACnetLandingCallStatus) -> Result<(), Error> {
if let LandingCallCommand::Direction(direction) = status.command {
super::checked(direction, super::direction_in_range)?;
}
Ok(())
}