rust_mqtt/client/options/will.rs
1use const_fn::const_fn;
2
3use crate::{
4 types::{MqttBinary, MqttString, QoS, TopicName, Will},
5 v5::property::WillDelayInterval,
6};
7
8/// Options for configuring the client's will or last will in a session.
9/// The server can publish a single PUBLISH packet in place of the client.
10/// This process behaves as if the will message was published by the client.
11/// The will is published at the earlier of the following scenarios:
12/// - The session of the client ends.
13/// - The will delay interval passes.
14#[derive(Debug, Clone)]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16pub struct Options<'c> {
17 /// The quality of service that the server publishes the will message with in place of the client.
18 pub will_qos: QoS,
19
20 /// The value of the retain flag of the will message published by the server in place of the client.
21 pub will_retain: bool,
22
23 /// The topic of the will publication.
24 pub will_topic: TopicName<'c>,
25
26 // Will properties starting here
27 /// The interval in seconds that passes after a disconnection before the server publishes the will.
28 /// The session of the client does not necessarily have to end for this scenario to happen.
29 /// The client can reconnect before this interval has passed to prevent the will publication.
30 /// If the value of the will delay interval is 0, the property is omitted on the network.
31 pub will_delay_interval: u32,
32
33 /// The payload format indicator property in the will publication. If present, this indicates
34 /// whether the will payload is valid UTF-8. If set to [`None`], the property is omitted on the
35 /// network.
36 pub payload_format_indicator: Option<bool>,
37
38 /// The message expiry interval in seconds of the will publication. If set to [`None`], the message
39 /// does not expire and the message expiry interval property is omitted on the network.
40 pub message_expiry_interval: Option<u32>,
41
42 /// The content type property in the will publication. If set to [`None`], the property is omitted
43 /// on the network.
44 pub content_type: Option<MqttString<'c>>,
45
46 /// The response topic property in the will publication. If set to [`None`], the property is omitted
47 /// on the network.
48 pub response_topic: Option<TopicName<'c>>,
49
50 /// The correlation data property in the will publication. If set to [`None`], the property is omitted
51 /// on the network.
52 pub correlation_data: Option<MqttBinary<'c>>,
53
54 /// The payload of the will publication.
55 pub will_message: MqttBinary<'c>,
56}
57
58impl<'c> Options<'c> {
59 /// Creates options with values coherent to the [`Default`] implementations of the fields and
60 /// [`QoS::AtMostOnce`].
61 #[must_use]
62 pub const fn new(topic: TopicName<'c>, message: MqttBinary<'c>) -> Options<'c> {
63 Options {
64 will_qos: QoS::AtMostOnce,
65 will_retain: false,
66 will_topic: topic,
67 will_delay_interval: 0,
68 payload_format_indicator: None,
69 message_expiry_interval: None,
70 content_type: None,
71 response_topic: None,
72 correlation_data: None,
73 will_message: message,
74 }
75 }
76
77 /// Sets the Quality of Service level.
78 #[must_use]
79 pub const fn qos(mut self, qos: QoS) -> Self {
80 self.will_qos = qos;
81 self
82 }
83 /// Sets the Quality of Service level to 1 (At Least Once).
84 #[must_use]
85 pub const fn at_least_once(self) -> Self {
86 self.qos(QoS::AtLeastOnce)
87 }
88 /// Sets the Quality of Service level to 1 (Exactly Once).
89 #[must_use]
90 pub const fn exactly_once(self) -> Self {
91 self.qos(QoS::ExactlyOnce)
92 }
93 /// Sets the retain flag in the will message to true.
94 #[must_use]
95 pub const fn retain(mut self) -> Self {
96 self.will_retain = true;
97 self
98 }
99 /// Sets the delay in seconds after which the will message is published.
100 #[must_use]
101 pub const fn delay_interval(mut self, delay_interval: u32) -> Self {
102 self.will_delay_interval = delay_interval;
103 self
104 }
105 /// Sets the payload format indicator property to true thus marking the payload of the will message.
106 /// as valid UTF-8.
107 #[must_use]
108 pub const fn payload_format_indicator(mut self, is_payload_utf8: bool) -> Self {
109 self.payload_format_indicator = Some(is_payload_utf8);
110 self
111 }
112 /// Sets the message expiry interval in seconds of the will message.
113 #[must_use]
114 pub const fn message_expiry_interval(mut self, message_expiry_interval: u32) -> Self {
115 self.message_expiry_interval = Some(message_expiry_interval);
116 self
117 }
118 /// Sets a custom content type of the will message.
119 #[const_fn(cfg(not(feature = "alloc")))]
120 #[must_use]
121 pub const fn content_type(mut self, content_type: MqttString<'c>) -> Self {
122 self.content_type = Some(content_type);
123 self
124 }
125 /// Marks the will message as a request by setting the response topic property.
126 #[const_fn(cfg(not(feature = "alloc")))]
127 #[must_use]
128 pub const fn response_topic(mut self, response_topic: TopicName<'c>) -> Self {
129 self.response_topic = Some(response_topic);
130 self
131 }
132 /// Sets the correlation data property in the request.
133 #[const_fn(cfg(not(feature = "alloc")))]
134 #[must_use]
135 pub const fn correlation_data(mut self, correlation_data: MqttBinary<'c>) -> Self {
136 self.correlation_data = Some(correlation_data);
137 self
138 }
139}
140
141impl<'c> Options<'c> {
142 pub(crate) fn as_borrowed_will(&'c self) -> Will<'c> {
143 Will {
144 will_topic: self.will_topic.as_borrowed(),
145 will_delay_interval: match self.will_delay_interval {
146 0 => None,
147 i => Some(WillDelayInterval(i)),
148 },
149 payload_format_indicator: self.payload_format_indicator.map(Into::into),
150 message_expiry_interval: self.message_expiry_interval.map(Into::into),
151 content_type: self
152 .content_type
153 .as_ref()
154 .map(MqttString::as_borrowed)
155 .map(Into::into),
156 response_topic: self
157 .response_topic
158 .as_ref()
159 .map(TopicName::as_borrowed)
160 .map(Into::into),
161 correlation_data: self
162 .correlation_data
163 .as_ref()
164 .map(MqttBinary::as_borrowed)
165 .map(Into::into),
166 will_message: self.will_message.as_borrowed(),
167 }
168 }
169}