use super::*;
use bacnet_services::write_property::{WritePropertyRequest, validate_priority};
#[doc(hidden)]
#[derive(Clone)]
pub enum EndpointOperationRequest {
Read(EndpointReadRequest),
Write(WritePropertyRequest),
}
#[doc(hidden)]
#[derive(Debug)]
pub enum EndpointOperationAck {
Read(EndpointReadAck),
Write,
}
impl EndpointOperationRequest {
pub fn validate(&self) -> Result<(), Error> {
match self {
Self::Read(request) => request.validate(),
Self::Write(request) => {
validate_priority(request.priority)?;
bacnet_encoding::constructed::validate_tlv_sequence(
&request.property_value,
"endpoint WriteProperty value",
)
}
}
}
pub fn identities(&self) -> Vec<(ObjectIdentifier, PropertyIdentifier, Option<u32>)> {
match self {
Self::Read(request) => request.identities(),
Self::Write(request) => vec![(
request.object_identifier,
request.property_identifier,
request.property_array_index,
)],
}
}
pub(super) fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
self.validate()?;
match self {
Self::Read(request) => request.encode(buf),
Self::Write(request) => request.encode(buf),
}
}
pub(super) fn service(&self) -> ConfirmedServiceChoice {
match self {
Self::Read(request) => request.service(),
Self::Write(_) => ConfirmedServiceChoice::WRITE_PROPERTY,
}
}
pub(super) fn terminal_policy(&self) -> TerminalPolicy {
match self {
Self::Read(_) => TerminalPolicy::ComplexAck,
Self::Write(_) => TerminalPolicy::SimpleAck,
}
}
pub(super) fn decode(&self, bytes: &[u8]) -> Result<EndpointOperationAck, Error> {
match self {
Self::Read(request) => request.decode(bytes).map(EndpointOperationAck::Read),
Self::Write(_) => Ok(EndpointOperationAck::Write),
}
}
}
impl EndpointOperationAck {
pub fn as_read(&self) -> Option<&EndpointReadAck> {
match self {
Self::Read(ack) => Some(ack),
Self::Write => None,
}
}
pub fn into_read(self) -> Result<EndpointReadAck, Error> {
match self {
Self::Read(ack) => Ok(ack),
Self::Write => Err(Error::Encoding(
"endpoint operation result kind mismatch".into(),
)),
}
}
pub fn into_write(self) -> Result<(), Error> {
match self {
Self::Write => Ok(()),
Self::Read(_) => Err(Error::Encoding(
"endpoint operation result kind mismatch".into(),
)),
}
}
pub fn into_property(self) -> Result<ReadPropertyACK, Error> {
self.into_read()?.into_property()
}
pub fn into_range(self) -> Result<bacnet_services::read_range::ReadRangeReply, Error> {
self.into_read()?.into_range()
}
pub fn into_multiple(self) -> Result<bacnet_services::rpm::ReadPropertyMultipleACK, Error> {
self.into_read()?.into_multiple()
}
}