use bytes::{Bytes, BytesMut};
use crate::packets::{
QoS, WireLength,
error::{DeserializeError, SerializeError},
mqtt_trait::{MqttAsyncRead, MqttAsyncWrite, MqttRead, MqttWrite},
};
use super::{LastWillProperties, VariableInteger};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LastWill {
pub qos: QoS,
pub retain: bool,
pub last_will_properties: LastWillProperties,
pub topic: Box<str>,
pub payload: Vec<u8>,
}
impl LastWill {
pub fn new<T: AsRef<str>, P: Into<Vec<u8>>>(qos: QoS, retain: bool, topic: T, payload: P) -> LastWill {
Self {
qos,
retain,
last_will_properties: LastWillProperties::default(),
topic: topic.as_ref().into(),
payload: payload.into(),
}
}
pub(crate) fn read(qos: QoS, retain: bool, buf: &mut Bytes) -> Result<Self, DeserializeError> {
let last_will_properties = LastWillProperties::read(buf)?;
let topic = Box::<str>::read(buf)?;
let payload = Vec::<u8>::read(buf)?;
Ok(Self {
qos,
retain,
topic,
payload,
last_will_properties,
})
}
pub(crate) async fn async_read<S>(qos: QoS, retain: bool, stream: &mut S) -> Result<(Self, usize), crate::packets::error::ReadError>
where
S: tokio::io::AsyncRead + Unpin,
{
let (last_will_properties, last_will_properties_read_bytes) = LastWillProperties::async_read(stream).await?;
let (topic, topic_read_bytes) = Box::<str>::async_read(stream).await?;
let (payload, payload_read_bytes) = Vec::<u8>::async_read(stream).await?;
let total_read_bytes = last_will_properties_read_bytes + topic_read_bytes + payload_read_bytes;
Ok((
Self {
qos,
retain,
last_will_properties,
topic,
payload,
},
total_read_bytes,
))
}
}
impl MqttWrite for LastWill {
fn write(&self, buf: &mut BytesMut) -> Result<(), SerializeError> {
self.last_will_properties.write(buf)?;
self.topic.write(buf)?;
self.payload.write(buf)?;
Ok(())
}
}
impl<S> MqttAsyncWrite<S> for LastWill
where
S: tokio::io::AsyncWrite + Unpin,
{
async fn async_write(&self, stream: &mut S) -> Result<usize, crate::packets::error::WriteError> {
let properties_written = self.last_will_properties.async_write(stream).await?;
let topic_written = self.topic.async_write(stream).await?;
let payload_written = self.payload.async_write(stream).await?;
Ok(properties_written + topic_written + payload_written)
}
}
impl WireLength for LastWill {
fn wire_len(&self) -> usize {
let property_len = self.last_will_properties.wire_len();
self.topic.wire_len() + self.payload.wire_len() + property_len.variable_integer_len() + property_len
}
}