use crate::{
properties::{Property, PropertyIdentifier},
types::{BinaryData, Properties, Utf8String},
varint::Varint,
ProtocolError, QoS, Retain,
};
use serde::Serialize;
#[derive(Debug)]
pub struct Will<'a> {
topic: &'a str,
data: &'a [u8],
qos: QoS,
retained: Retain,
properties: &'a [Property<'a>],
}
#[derive(Serialize)]
struct WillMessage<'a> {
properties: Properties<'a>,
topic: Utf8String<'a>,
data: BinaryData<'a>,
}
impl<'a> Will<'a> {
pub fn new(
topic: &'a str,
data: &'a [u8],
properties: &'a [Property<'a>],
) -> Result<Self, ProtocolError> {
for property in properties {
match property.into() {
PropertyIdentifier::WillDelayInterval
| PropertyIdentifier::PayloadFormatIndicator
| PropertyIdentifier::MessageExpiryInterval
| PropertyIdentifier::ContentType
| PropertyIdentifier::ResponseTopic
| PropertyIdentifier::CorrelationData
| PropertyIdentifier::UserProperty => {}
_ => return Err(ProtocolError::InvalidProperty),
}
}
Ok(Self {
topic,
data,
properties,
qos: QoS::AtMostOnce,
retained: Retain::NotRetained,
})
}
pub(crate) fn serialize<'b>(
&self,
buf: &'b mut [u8],
) -> Result<SerializedWill<'b>, crate::ser::Error> {
let message = WillMessage {
topic: Utf8String(self.topic),
properties: Properties::Slice(self.properties),
data: BinaryData(self.data),
};
let mut serializer = crate::ser::MqttSerializer::new_without_header(buf);
message.serialize(&mut serializer)?;
Ok(SerializedWill {
qos: self.qos,
retained: self.retained,
contents: serializer.finish(),
})
}
pub(crate) fn serialized_len(&self) -> usize {
let prop_len = {
let prop_size = Properties::Slice(self.properties).size();
Varint(prop_size as u32).len() + prop_size
};
let topic_len = self.topic.len() + core::mem::size_of::<u16>();
let payload_len = self.data.len() + core::mem::size_of::<u16>();
topic_len + payload_len + prop_len
}
pub fn retained(mut self) -> Self {
self.retained = Retain::Retained;
self
}
pub fn qos(mut self, qos: QoS) -> Self {
self.qos = qos;
self
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub(crate) struct SerializedWill<'a> {
pub(crate) qos: QoS,
pub(crate) retained: Retain,
pub(crate) contents: &'a [u8],
}