dbus_message_parser/message/header/
header_struct.rs1use super::{HeaderError, HeaderFields};
2use crate::{
3 message::{Message, MessageFlags, MessageType},
4 value::{Bus, Error, Interface, Member, ObjectPath, Type, Value},
5};
6use std::convert::TryInto;
7
8macro_rules! get_field {
9 ($(#[$meta:meta])* $function:ident, $field:ident, $return:ty $(,$as_ref:ident)?) => {
10 $(#[$meta])*
11 #[inline]
12 pub const fn $function(&self) -> Option<$return> {
13 self.fields.$field$(.$as_ref())?
14 }
15 };
16}
17
18macro_rules! has_field {
19 ($(#[$meta:meta])* $function:ident, $field:ident) => {
20 $(#[$meta])*
21 #[inline]
22 pub const fn $function(&self) -> bool {
23 self.fields.$field.is_some()
24 }
25 };
26}
27
28#[inline]
29fn check_header_fields(
30 message_type: MessageType,
31 fields: &HeaderFields,
32) -> Result<(), HeaderError> {
33 match message_type {
34 MessageType::MethodCall => {
35 if fields.path.is_none() {
36 return Err(HeaderError::MissingPath);
37 }
38
39 if fields.member.is_none() {
40 return Err(HeaderError::MissingMember);
41 }
42 }
43 MessageType::Signal => {
44 if fields.path.is_none() {
45 return Err(HeaderError::MissingPath);
46 }
47
48 if fields.interface.is_none() {
49 return Err(HeaderError::MissingInterface);
50 }
51
52 if fields.member.is_none() {
53 return Err(HeaderError::MissingMember);
54 }
55 }
56 MessageType::Error => {
57 if fields.error_name.is_none() {
58 return Err(HeaderError::MissingErrorName);
59 }
60
61 if fields.reply_serial.is_none() {
62 return Err(HeaderError::MissingReplySerial);
63 }
64 }
65 MessageType::MethodReturn => {
66 if fields.reply_serial.is_none() {
67 return Err(HeaderError::MissingReplySerial);
68 }
69 }
70 }
71 Ok(())
72}
73
74#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq)]
78pub struct Header {
79 pub(crate) is_le: bool,
80 pub(crate) message_type: MessageType,
81 pub(crate) message_flags: MessageFlags,
82 pub(crate) version: u8,
83 pub(crate) serial: u32,
84 pub(crate) fields: HeaderFields,
85}
86
87impl Header {
88 pub fn new(
93 is_le: bool,
94 message_type: MessageType,
95 message_flags: MessageFlags,
96 version: u8,
97 serial: u32,
98 fields: HeaderFields,
99 ) -> Result<Header, HeaderError> {
100 check_header_fields(message_type, &fields)?;
101
102 let header = Header {
103 is_le,
104 message_type,
105 message_flags,
106 version,
107 serial,
108 fields,
109 };
110
111 Ok(header)
112 }
113
114 #[inline]
116 pub const fn get_serial(&self) -> u32 {
117 self.serial
118 }
119
120 get_field!(
121 get_path,
125 path,
126 &ObjectPath,
127 as_ref
128 );
129
130 has_field!(
131 has_path,
135 path
136 );
137
138 get_field!(
139 get_interface,
143 interface,
144 &Interface,
145 as_ref
146 );
147
148 has_field!(
149 has_interface,
153 interface
154 );
155
156 get_field!(
157 get_member,
161 member,
162 &Member,
163 as_ref
164 );
165
166 has_field!(
167 has_member,
171 member
172 );
173
174 get_field!(
175 get_error_name,
179 error_name,
180 &Error,
181 as_ref
182 );
183
184 has_field!(
185 has_error_name,
189 error_name
190 );
191
192 get_field!(
193 get_destination,
197 destination,
198 &Bus,
199 as_ref
200 );
201
202 has_field!(
203 has_destination,
207 destination
208 );
209
210 get_field!(
211 get_sender,
215 sender,
216 &Bus,
217 as_ref
218 );
219
220 has_field!(
221 has_sender,
225 sender
226 );
227
228 get_field!(
229 get_reply_serial,
233 reply_serial,
234 u32
235 );
236
237 has_field!(
238 has_reply_serial,
242 reply_serial
243 );
244
245 #[inline]
249 pub fn get_signature(&self) -> Option<&[Type]> {
250 self.fields.signature.as_deref()
251 }
252
253 has_field!(
254 has_signature,
258 signature
259 );
260
261 #[cfg(target_family = "unix")]
262 get_field!(
263 get_unix_fds,
267 unix_fds,
268 u32
269 );
270
271 #[cfg(target_family = "unix")]
272 has_field!(
273 has_unix_fds,
277 unix_fds
278 );
279
280 pub fn method_return(&self) -> Result<Message, Message> {
286 if let MessageType::MethodCall = self.message_type {
287 let message_type = MessageType::MethodReturn;
288
289 let message_flags = MessageFlags::NO_REPLY_EXPECTED;
290
291 let mut fields = HeaderFields::default();
292
293 if let Some(sender) = self.get_sender() {
294 fields.destination = Some(sender.clone());
295 }
296
297 if let Some(destination) = self.get_destination() {
298 fields.sender = Some(destination.clone());
299 }
300
301 fields.reply_serial = Some(self.get_serial());
302
303 let header = Header {
304 is_le: self.is_le,
305 message_type,
306 message_flags,
307 version: 1,
308 serial: 0,
309 fields,
310 };
311 Ok(Message {
312 header,
313 body: Vec::new(),
314 })
315 } else {
316 Err(self.error(
317 "org.freedesktop.DBus.Error.MessageType".try_into().unwrap(),
318 "Message is not a method call".to_string(),
319 ))
320 }
321 }
322
323 pub fn unknown_property(&self, property: &str) -> Message {
327 let message = format!("does not have a property {}", property);
328 self.error(
329 "org.freedesktop.DBus.Error.UnknownProperty"
330 .try_into()
331 .unwrap(),
332 message,
333 )
334 }
335
336 pub fn unknown_path(&self) -> Option<Message> {
340 let path = self.get_path()?;
341 let message = format!("does not have a path {}", path);
342 let msg = self.error(
343 "org.freedesktop.DBus.Error.UnknownPath".try_into().unwrap(),
344 message,
345 );
346 Some(msg)
347 }
348
349 pub fn unknown_interface(&self) -> Option<Message> {
353 let interface = self.get_interface()?;
354 let message = format!("does not have an interface {}", interface);
355 let msg = self.error(
356 "org.freedesktop.DBus.Error.UnknownInterface"
357 .try_into()
358 .unwrap(),
359 message,
360 );
361 Some(msg)
362 }
363
364 pub fn unknown_member(&self) -> Option<Message> {
368 let member = self.get_member()?;
369 let message = format!("does not have a member {}", member);
370 let msg = self.error(
371 "org.freedesktop.DBus.Error.UnknownMember"
372 .try_into()
373 .unwrap(),
374 message,
375 );
376 Some(msg)
377 }
378
379 pub fn invalid_args(&self, reason: String) -> Message {
383 self.error(
384 "org.freedesktop.DBus.Error.InvalidArgs".try_into().unwrap(),
385 reason,
386 )
387 }
388
389 pub fn error(&self, error: Error, message: String) -> Message {
393 let message_type = MessageType::Error;
394
395 let message_flags = MessageFlags::NO_REPLY_EXPECTED;
396
397 let mut fields = HeaderFields::default();
398
399 if let Some(sender) = self.get_sender() {
400 fields.destination = Some(sender.clone());
401 }
402
403 if let Some(destination) = self.get_destination() {
404 fields.sender = Some(destination.clone());
405 }
406
407 fields.reply_serial = Some(self.get_serial());
408 fields.error_name = Some(error);
409
410 let header = Header {
411 is_le: self.is_le,
412 message_type,
413 message_flags,
414 version: 1,
415 serial: 0,
416 fields,
417 };
418 Message {
419 header,
420 body: vec![Value::String(message)],
421 }
422 }
423
424 pub fn get_type(&self) -> MessageType {
426 self.message_type
427 }
428}