1use crate::{
2 properties::{Property, PropertyIdentifier},
3 types::{BinaryData, Properties, Utf8String},
4 varint::Varint,
5 ProtocolError, QoS, Retain,
6};
7
8use serde::Serialize;
9
10#[derive(Debug)]
11pub struct Will<'a> {
12 topic: &'a str,
13 data: &'a [u8],
14 qos: QoS,
15 retained: Retain,
16 properties: &'a [Property<'a>],
17}
18
19#[derive(Serialize)]
20struct WillMessage<'a> {
21 properties: Properties<'a>,
22 topic: Utf8String<'a>,
23 data: BinaryData<'a>,
24}
25
26impl<'a> Will<'a> {
27 pub fn new(
34 topic: &'a str,
35 data: &'a [u8],
36 properties: &'a [Property<'a>],
37 ) -> Result<Self, ProtocolError> {
38 for property in properties {
40 match property.into() {
41 PropertyIdentifier::WillDelayInterval
42 | PropertyIdentifier::PayloadFormatIndicator
43 | PropertyIdentifier::MessageExpiryInterval
44 | PropertyIdentifier::ContentType
45 | PropertyIdentifier::ResponseTopic
46 | PropertyIdentifier::CorrelationData
47 | PropertyIdentifier::UserProperty => {}
48 _ => return Err(ProtocolError::InvalidProperty),
49 }
50 }
51
52 Ok(Self {
53 topic,
54 data,
55 properties,
56 qos: QoS::AtMostOnce,
57 retained: Retain::NotRetained,
58 })
59 }
60
61 pub(crate) fn serialize<'b>(
63 &self,
64 buf: &'b mut [u8],
65 ) -> Result<SerializedWill<'b>, crate::ser::Error> {
66 let message = WillMessage {
67 topic: Utf8String(self.topic),
68 properties: Properties::Slice(self.properties),
69 data: BinaryData(self.data),
70 };
71
72 let mut serializer = crate::ser::MqttSerializer::new_without_header(buf);
73 message.serialize(&mut serializer)?;
74 Ok(SerializedWill {
75 qos: self.qos,
76 retained: self.retained,
77 contents: serializer.finish(),
78 })
79 }
80
81 pub(crate) fn serialized_len(&self) -> usize {
83 let prop_len = {
84 let prop_size = Properties::Slice(self.properties).size();
85 Varint(prop_size as u32).len() + prop_size
86 };
87 let topic_len = self.topic.len() + core::mem::size_of::<u16>();
88 let payload_len = self.data.len() + core::mem::size_of::<u16>();
89 topic_len + payload_len + prop_len
90 }
91
92 pub fn retained(mut self) -> Self {
94 self.retained = Retain::Retained;
95 self
96 }
97
98 pub fn qos(mut self, qos: QoS) -> Self {
103 self.qos = qos;
104 self
105 }
106}
107
108#[derive(Debug, Copy, Clone, PartialEq)]
110pub(crate) struct SerializedWill<'a> {
111 pub(crate) qos: QoS,
112 pub(crate) retained: Retain,
113 pub(crate) contents: &'a [u8],
114}