Skip to main content

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}