Coverage Report

Created: 2026-01-27 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dbus-0.9.7/src/message.rs
Line
Count
Source
1
//! Contains structs and traits closely related to D-Bus messages.
2
3
use std::{fmt, ptr};
4
use super::{ffi, Error, libc, init_dbus};
5
use crate::strings::{BusName, Path, Interface, Member, ErrorName};
6
use std::ffi::CStr;
7
8
use super::arg::{Append, AppendAll, IterAppend, ReadAll, Get, Iter, Arg, RefArg, TypeMismatchError};
9
10
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
11
/// One of the four different message types.
12
pub enum MessageType {
13
    /// This is a method call D-Bus message
14
    MethodCall = 1,
15
    /// This is a method return Ok D-Bus message, used when the method call message was successfully processed
16
    MethodReturn = 2,
17
    /// This is a method return with error D-Bus message, used when the method call message could not be handled
18
    Error = 3,
19
    /// This is a signal, usually sent to whoever wants to listen
20
    Signal = 4,
21
}
22
23
impl<'a> TryFrom<&'a str> for MessageType {
24
    type Error = ();
25
26
0
    fn try_from(value: &'a str) -> Result<Self, <crate::message::MessageType as TryFrom<&'a str>>::Error> {
27
0
        match value {
28
0
            "error" => Ok(MessageType::Error),
29
0
            "method_call" => Ok(MessageType::MethodCall),
30
0
            "method_return" => Ok(MessageType::MethodReturn),
31
0
            "signal" => Ok(MessageType::Signal),
32
0
            _ => Err(())
33
        }
34
0
    }
35
}
36
37
mod signalargs;
38
pub use self::signalargs::SignalArgs;
39
40
mod matchrule;
41
pub use self::matchrule::MatchRule;
42
use std::convert::TryFrom;
43
44
mod parser;
45
pub use self::parser::Error as MatchRuleParserError;
46
47
/// A D-Bus message. A message contains headers - usually destination address, path, interface and member,
48
/// and a list of arguments.
49
pub struct Message {
50
    msg: *mut ffi::DBusMessage,
51
}
52
53
unsafe impl Send for Message {}
54
55
impl Message {
56
    /// Creates a new method call message.
57
0
    pub fn new_method_call<'d, 'p, 'i, 'm, D, P, I, M>(destination: D, path: P, iface: I, method: M) -> Result<Message, String>
58
0
    where D: Into<BusName<'d>>, P: Into<Path<'p>>, I: Into<Interface<'i>>, M: Into<Member<'m>> {
59
0
        init_dbus();
60
0
        let (d, p, i, m) = (destination.into(), path.into(), iface.into(), method.into());
61
0
        let ptr = unsafe {
62
0
            ffi::dbus_message_new_method_call(d.as_ptr(), p.as_ptr(), i.as_ptr(), m.as_ptr())
63
        };
64
0
        if ptr.is_null() { Err("D-Bus error: dbus_message_new_method_call failed".into()) }
65
0
        else { Ok(Message { msg: ptr}) }
66
0
    }
67
68
    /// Creates a new method call message.
69
0
    pub fn method_call(destination: &BusName, path: &Path, iface: &Interface, name: &Member) -> Message {
70
0
        init_dbus();
71
0
        let ptr = unsafe {
72
0
            ffi::dbus_message_new_method_call(destination.as_ptr(), path.as_ptr(),
73
0
                iface.as_ptr(), name.as_ptr())
74
        };
75
0
        if ptr.is_null() { panic!("D-Bus error: dbus_message_new_method_call failed") }
76
0
        Message { msg: ptr}
77
0
    }
78
79
    /// Creates a new message that is a replica of this message, but without a serial.
80
    ///
81
    /// May fail if out of memory or file descriptors.
82
0
    pub fn duplicate(&self) -> Result<Self, String> {
83
0
        let ptr = unsafe {
84
0
            ffi::dbus_message_copy(self.msg)
85
        };
86
0
        if ptr.is_null() {
87
0
            Err("D-Bus error: dbus_message_copy failed".into())
88
        } else {
89
0
            Ok(Message { msg: ptr })
90
        }
91
0
    }
92
93
    /// Creates a new method call message.
94
0
    pub fn call_with_args<'d, 'p, 'i, 'm, A, D, P, I, M>(destination: D, path: P, iface: I, method: M, args: A) -> Message
95
0
    where D: Into<BusName<'d>>, P: Into<Path<'p>>, I: Into<Interface<'i>>, M: Into<Member<'m>>, A: AppendAll {
96
0
        let mut msg = Message::method_call(&destination.into(), &path.into(), &iface.into(), &method.into());
97
0
        msg.append_all(args);
98
0
        msg
99
0
    }
100
101
    /// Creates a new signal message.
102
0
    pub fn new_signal<P, I, M>(path: P, iface: I, name: M) -> Result<Message, String>
103
0
    where P: Into<String>, I: Into<String>, M: Into<String> {
104
0
        init_dbus();
105
106
0
        let p = Path::new(path)?;
107
0
        let i = Interface::new(iface)?;
108
0
        let m = Member::new(name)?;
109
110
0
        let ptr = unsafe {
111
0
            ffi::dbus_message_new_signal(p.as_ptr(), i.as_ptr(), m.as_ptr())
112
        };
113
0
        if ptr.is_null() { Err("D-Bus error: dbus_message_new_signal failed".into()) }
114
0
        else { Ok(Message { msg: ptr}) }
115
0
    }
116
117
    /// Creates a new signal message.
118
0
    pub fn signal(path: &Path, iface: &Interface, name: &Member) -> Message {
119
0
        init_dbus();
120
0
        let ptr = unsafe {
121
0
            ffi::dbus_message_new_signal(path.as_ptr(), iface.as_ptr(), name.as_ptr())
122
        };
123
0
        if ptr.is_null() { panic!("D-Bus error: dbus_message_new_signal failed") }
124
0
        Message { msg: ptr}
125
0
    }
126
127
    /// Creates a method reply for this method call.
128
0
    pub fn new_method_return(m: &Message) -> Option<Message> {
129
0
        let ptr = unsafe { ffi::dbus_message_new_method_return(m.msg) };
130
0
        if ptr.is_null() { None } else { Some(Message { msg: ptr} ) }
131
0
    }
132
133
    /// Creates a method return (reply) for this method call.
134
0
    pub fn method_return(&self) -> Message {
135
0
        let ptr = unsafe { ffi::dbus_message_new_method_return(self.msg) };
136
0
        if ptr.is_null() { panic!("D-Bus error: dbus_message_new_method_return failed") }
137
0
        Message {msg: ptr}
138
0
    }
139
140
    /// Creates a reply for a method call message.
141
    ///
142
    /// Panics if called for a message which is not a method call.
143
0
    pub fn return_with_args<A: AppendAll>(&self, args: A) -> Message {
144
0
        let mut m = self.method_return();
145
0
        m.append_all(args);
146
0
        m
147
0
    }
148
149
    /// Creates a new error reply
150
0
    pub fn error(&self, error_name: &ErrorName, error_message: &CStr) -> Message {
151
0
        let ptr = unsafe { ffi::dbus_message_new_error(self.msg, error_name.as_ptr(), error_message.as_ptr()) };
152
0
        if ptr.is_null() { panic!("D-Bus error: dbus_message_new_error failed") }
153
0
        Message { msg: ptr}
154
0
    }
155
156
    /// Get the MessageItems that make up the message.
157
    ///
158
    /// Note: use `iter_init` or `get1`/`get2`/etc instead for faster access to the arguments.
159
    /// This method is provided for backwards compatibility.
160
0
    pub fn get_items(&self) -> Vec<crate::arg::messageitem::MessageItem> {
161
0
        let mut i = self.iter_init();
162
0
        let mut v = vec!();
163
0
        while let Some(z) = crate::arg::messageitem::MessageItem::get(&mut i) { v.push(z); i.next(); }
164
0
        v
165
0
    }
166
167
    /// Get the D-Bus serial of a message, if one was specified.
168
0
    pub fn get_serial(&self) -> Option<u32> {
169
0
        let x = unsafe { ffi::dbus_message_get_serial(self.msg) };
170
0
        if x == 0 { None } else { Some(x) }
171
0
    }
172
173
    /// Get the serial of the message this message is a reply to, if present.
174
0
    pub fn get_reply_serial(&self) -> Option<u32> {
175
0
        let s = unsafe { ffi::dbus_message_get_reply_serial(self.msg) };
176
0
        if s == 0 { None } else { Some(s) }
177
0
    }
178
179
    /// Returns true if the message does not expect a reply.
180
0
    pub fn get_no_reply(&self) -> bool { unsafe { ffi::dbus_message_get_no_reply(self.msg) != 0 } }
181
182
    /// Set whether or not the message expects a reply.
183
    ///
184
    /// Set to true if you send a method call and do not want a reply.
185
0
    pub fn set_no_reply(&mut self, v: bool) {
186
0
        unsafe { ffi::dbus_message_set_no_reply(self.msg, if v { 1 } else { 0 }) }
187
0
    }
188
189
    /// Returns true if the message can cause a service to be auto-started.
190
0
    pub fn get_auto_start(&self) -> bool { unsafe { ffi::dbus_message_get_auto_start(self.msg) != 0 } }
191
192
    /// Sets whether or not the message can cause a service to be auto-started.
193
    ///
194
    /// Defaults to true.
195
0
    pub fn set_auto_start(&mut self, v: bool) {
196
0
        unsafe { ffi::dbus_message_set_auto_start(self.msg, if v { 1 } else { 0 }) }
197
0
    }
198
199
    /// Add one or more MessageItems to this Message.
200
    ///
201
    /// Note: using `append1`, `append2` or `append3` might be faster, especially for large arrays.
202
    /// This method is provided for backwards compatibility.
203
0
    pub fn append_items(&mut self, v: &[crate::arg::messageitem::MessageItem]) {
204
0
        let mut ia = IterAppend::new(self);
205
0
        for a in v { a.append_by_ref(&mut ia); }
206
0
    }
207
208
    /// Appends one argument to this message.
209
    /// Use in builder style: e g `m.method_return().append1(7i32)`
210
0
    pub fn append1<A: Append>(mut self, a: A) -> Self {
211
0
        {
212
0
            let mut m = IterAppend::new(&mut self);
213
0
            m.append(a);
214
0
        }
215
0
        self
216
0
    }
217
218
    /// Appends two arguments to this message.
219
    /// Use in builder style: e g `m.method_return().append2(7i32, 6u8)`
220
0
    pub fn append2<A1: Append, A2: Append>(mut self, a1: A1, a2: A2) -> Self {
221
0
        {
222
0
            let mut m = IterAppend::new(&mut self);
223
0
            m.append(a1); m.append(a2);
224
0
        }
225
0
        self
226
0
    }
227
228
    /// Appends three arguments to this message.
229
    /// Use in builder style: e g `m.method_return().append3(7i32, 6u8, true)`
230
0
    pub fn append3<A1: Append, A2: Append, A3: Append>(mut self, a1: A1, a2: A2, a3: A3) -> Self {
231
0
        {
232
0
            let mut m = IterAppend::new(&mut self);
233
0
            m.append(a1); m.append(a2); m.append(a3);
234
0
        }
235
0
        self
236
0
    }
237
238
    /// Appends RefArgs to this message.
239
    /// Use in builder style: e g `m.method_return().append_ref(&[7i32, 6u8, true])`
240
0
    pub fn append_ref<A: RefArg>(mut self, r: &[A]) -> Self {
241
        {
242
0
            let mut m = IterAppend::new(&mut self);
243
0
            for rr in r {
244
0
                rr.append(&mut m);
245
0
            }
246
        }
247
0
        self
248
0
    }
249
250
    /// Appends arguments to a message.
251
0
    pub fn append_all<A: AppendAll>(&mut self, a: A) {
252
0
        let mut m = IterAppend::new(self);
253
0
        a.append(&mut m);
254
0
    }
255
256
    /// Gets the first argument from the message, if that argument is of type G1.
257
    /// Returns None if there are not enough arguments, or if types don't match.
258
0
    pub fn get1<'a, G1: Get<'a>>(&'a self) -> Option<G1> {
259
0
        let mut i = Iter::new(&self);
260
0
        i.get()
261
0
    }
262
263
    /// Gets the first two arguments from the message, if those arguments are of type G1 and G2.
264
    /// Returns None if there are not enough arguments, or if types don't match.
265
0
    pub fn get2<'a, G1: Get<'a>, G2: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>) {
266
0
        let mut i = Iter::new(&self);
267
0
        let g1 = i.get();
268
0
        if !i.next() { return (g1, None); }
269
0
        (g1, i.get())
270
0
    }
271
272
    /// Gets the first three arguments from the message, if those arguments are of type G1, G2 and G3.
273
    /// Returns None if there are not enough arguments, or if types don't match.
274
0
    pub fn get3<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>) {
275
0
        let mut i = Iter::new(&self);
276
0
        let g1 = i.get();
277
0
        if !i.next() { return (g1, None, None) }
278
0
        let g2 = i.get();
279
0
        if !i.next() { return (g1, g2, None) }
280
0
        (g1, g2, i.get())
281
0
    }
282
283
    /// Gets the first four arguments from the message, if those arguments are of type G1, G2, G3 and G4.
284
    /// Returns None if there are not enough arguments, or if types don't match.
285
0
    pub fn get4<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>) {
286
0
        let mut i = Iter::new(&self);
287
0
        let g1 = i.get();
288
0
        if !i.next() { return (g1, None, None, None) }
289
0
        let g2 = i.get();
290
0
        if !i.next() { return (g1, g2, None, None) }
291
0
        let g3 = i.get();
292
0
        if !i.next() { return (g1, g2, g3, None) }
293
0
        (g1, g2, g3, i.get())
294
0
    }
295
296
    /// Gets the first five arguments from the message, if those arguments are of type G1, G2, G3 and G4.
297
    /// Returns None if there are not enough arguments, or if types don't match.
298
    /// Note: If you need more than five arguments, use `iter_init` instead.
299
0
    pub fn get5<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>, G5: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>, Option<G5>) {
300
0
        let mut i = Iter::new(&self);
301
0
        let g1 = i.get();
302
0
        if !i.next() { return (g1, None, None, None, None) }
303
0
        let g2 = i.get();
304
0
        if !i.next() { return (g1, g2, None, None, None) }
305
0
        let g3 = i.get();
306
0
        if !i.next() { return (g1, g2, g3, None, None) }
307
0
        let g4 = i.get();
308
0
        if !i.next() { return (g1, g2, g3, g4, None) }
309
0
        (g1, g2, g3, g4, i.get())
310
0
    }
311
312
    /// Gets the first argument from the message, if that argument is of type G1.
313
    ///
314
    /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
315
0
    pub fn read1<'a, G1: Arg + Get<'a>>(&'a self) -> Result<G1, TypeMismatchError> {
316
0
        let mut i = Iter::new(&self);
317
0
        i.read()
318
0
    }
319
320
    /// Gets the first two arguments from the message, if those arguments are of type G1 and G2.
321
    ///
322
    /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
323
0
    pub fn read2<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>>(&'a self) -> Result<(G1, G2), TypeMismatchError> {
324
0
        let mut i = Iter::new(&self);
325
0
        Ok((i.read()?, i.read()?))
326
0
    }
327
328
    /// Gets the first three arguments from the message, if those arguments are of type G1, G2 and G3.
329
    ///
330
    /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
331
0
    pub fn read3<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>>(&'a self) ->
332
0
        Result<(G1, G2, G3), TypeMismatchError> {
333
0
        let mut i = Iter::new(&self);
334
0
        Ok((i.read()?, i.read()?, i.read()?))
335
0
    }
336
337
    /// Gets the first four arguments from the message, if those arguments are of type G1, G2, G3 and G4.
338
    ///
339
    /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
340
0
    pub fn read4<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>>(&'a self) ->
341
0
        Result<(G1, G2, G3, G4), TypeMismatchError> {
342
0
        let mut i = Iter::new(&self);
343
0
        Ok((i.read()?, i.read()?, i.read()?, i.read()?))
344
0
    }
345
346
    /// Gets the first five arguments from the message, if those arguments are of type G1, G2, G3, G4 and G5.
347
    ///
348
    /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
349
    /// Note: If you need more than five arguments, use `iter_init` instead.
350
0
    pub fn read5<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>, G5: Arg + Get<'a>>(&'a self) ->
351
0
        Result<(G1, G2, G3, G4, G5), TypeMismatchError> {
352
0
        let mut i = Iter::new(&self);
353
0
        Ok((i.read()?, i.read()?, i.read()?, i.read()?, i.read()?))
354
0
    }
355
356
    /// Gets arguments from a message.
357
    ///
358
    /// If this was an error reply or if types mismatch, an error is returned.
359
0
    pub fn read_all<R: ReadAll>(&self) -> Result<R, Error> {
360
0
        self.set_error_from_msg()?;
361
0
        Ok(R::read(&mut self.iter_init())?)
362
0
    }
363
364
    /// Returns a struct for retreiving the arguments from a message. Supersedes get_items().
365
0
    pub fn iter_init(&self) -> Iter { Iter::new(&self) }
366
367
    /// Gets the MessageType of the Message.
368
0
    pub fn msg_type(&self) -> MessageType {
369
0
        match unsafe { ffi::dbus_message_get_type(self.msg) } {
370
0
            1 => MessageType::MethodCall,
371
0
            2 => MessageType::MethodReturn,
372
0
            3 => MessageType::Error,
373
0
            4 => MessageType::Signal,
374
0
            x => panic!("Invalid message type {}", x),
375
        }
376
0
    }
377
378
0
    fn msg_internal_str<'a>(&'a self, c: *const libc::c_char) -> Option<&'a str> {
379
0
        if c.is_null() { return None };
380
0
        let cc = unsafe { CStr::from_ptr(c) };
381
0
        std::str::from_utf8(cc.to_bytes_with_nul()).ok()
382
0
    }
383
384
    /// Gets the name of the connection that originated this message.
385
0
    pub fn sender(&self) -> Option<BusName> {
386
0
        self.msg_internal_str(unsafe { ffi::dbus_message_get_sender(self.msg) })
387
0
            .map(|s| unsafe { BusName::from_slice_unchecked(s) })
388
0
    }
389
390
    /// Gets the object path this Message is being sent to.
391
0
    pub fn path(&self) -> Option<Path> {
392
0
        self.msg_internal_str(unsafe { ffi::dbus_message_get_path(self.msg) })
393
0
            .map(|s| unsafe { Path::from_slice_unchecked(s) })
394
0
    }
395
396
    /// Gets the destination this Message is being sent to.
397
0
    pub fn destination(&self) -> Option<BusName> {
398
0
        self.msg_internal_str(unsafe { ffi::dbus_message_get_destination(self.msg) })
399
0
            .map(|s| unsafe { BusName::from_slice_unchecked(s) })
400
0
    }
401
402
    /// Sets the destination of this Message
403
    ///
404
    /// If dest is none, that means broadcast to all relevant destinations.
405
0
    pub fn set_destination(&mut self, dest: Option<BusName>) {
406
0
        let c_dest = dest.as_ref().map(|d| d.as_cstr().as_ptr()).unwrap_or(ptr::null());
407
0
        assert!(unsafe { ffi::dbus_message_set_destination(self.msg, c_dest) } != 0);
408
0
    }
409
410
    /// Gets the interface this Message is being sent to.
411
0
    pub fn interface(&self) -> Option<Interface> {
412
0
        self.msg_internal_str(unsafe { ffi::dbus_message_get_interface(self.msg) })
413
0
            .map(|s| unsafe { Interface::from_slice_unchecked(s) })
414
0
    }
415
416
    /// Gets the interface member being called.
417
0
    pub fn member(&self) -> Option<Member> {
418
0
        self.msg_internal_str(unsafe { ffi::dbus_message_get_member(self.msg) })
419
0
            .map(|s| unsafe { Member::from_slice_unchecked(s) })
420
0
    }
421
422
    /// When the remote end returns an error, the message itself is
423
    /// correct but its contents is an error. This method will
424
    /// transform such an error to a D-Bus Error or otherwise return
425
    /// the original message.
426
0
    pub fn as_result(&mut self) -> Result<&mut Message, Error> {
427
0
        self.set_error_from_msg().map(|_| self)
428
0
    }
429
430
0
    pub (crate) fn set_error_from_msg(&self) -> Result<(), Error> {
431
0
        let mut e = Error::empty();
432
0
        if unsafe { ffi::dbus_set_error_from_message(e.get_mut(), self.msg) } != 0 { Err(e) }
433
0
        else { Ok(()) }
434
0
    }
435
436
0
    pub (crate) fn ptr(&self) -> *mut ffi::DBusMessage { self.msg }
437
438
0
    pub (crate) fn from_ptr(ptr: *mut ffi::DBusMessage, add_ref: bool) -> Message {
439
0
        if add_ref {
440
0
            unsafe { ffi::dbus_message_ref(ptr) };
441
0
        }
442
0
        Message { msg: ptr }
443
0
    }
444
445
    /// Sets serial number manually - mostly for internal use
446
    ///
447
    /// When sending a message, a serial will be automatically assigned, so you don't need to call
448
    /// this method. However, it can be very useful in test code that is supposed to handle a method call.
449
    /// This way, you can create a method call and handle it without sending it to a real D-Bus instance.
450
0
    pub fn set_serial(&mut self, val: u32) {
451
0
        unsafe { ffi::dbus_message_set_serial(self.msg, val) };
452
0
    }
453
454
    /// Marshals a message - mostly for internal use
455
    ///
456
    /// The function f will be called one or more times with bytes to be written somewhere.
457
    /// You should call set_serial to manually set a serial number before calling this function
458
0
    pub fn marshal<E, F: FnMut(&[u8]) -> Result<(), E>>(&self, mut f: F) -> Result<(), E> {
459
0
        let mut len = 0;
460
0
        let mut data = ptr::null_mut();
461
0
        if unsafe { ffi::dbus_message_marshal(self.msg, &mut data, &mut len) } == 0 {
462
0
            panic!("out of memory");
463
0
        }
464
0
        let s = unsafe { std::slice::from_raw_parts(data as *mut u8 as *const u8, len as usize) };
465
0
        let r = f(s);
466
0
        unsafe { ffi::dbus_free(data as *mut _) };
467
0
        r
468
0
    }
469
470
    /// Demarshals a message - mostly for internal use
471
0
    pub fn demarshal(data: &[u8]) -> Result<Self, Error> {
472
0
        let mut e = Error::empty();
473
0
        let p = unsafe { ffi::dbus_message_demarshal(data.as_ptr() as *const _, data.len() as _, e.get_mut()) };
474
0
        if p == ptr::null_mut() {
475
0
            Err(e)
476
        } else {
477
0
            Ok(Self::from_ptr(p, false))
478
        }
479
0
    }
480
481
    /// Returns the size of the message - mostly for internal use
482
    ///
483
    /// Returns Err(()) on protocol errors. Make sure you have at least 16 bytes in the buffer
484
    /// before calling this method.
485
0
    pub fn demarshal_bytes_needed(data: &[u8]) -> Result<usize, ()> {
486
        const MIN_HEADER: usize = 16;
487
0
        if data.len() < MIN_HEADER { return Ok(MIN_HEADER); }
488
0
        let x = unsafe { ffi::dbus_message_demarshal_bytes_needed(data.as_ptr() as *const _, data.len() as _) };
489
0
        if x < MIN_HEADER as _ { Err(()) } else { Ok(x as usize) }
490
0
    }
491
492
}
493
494
impl Drop for Message {
495
0
    fn drop(&mut self) {
496
0
        unsafe {
497
0
            ffi::dbus_message_unref(self.msg);
498
0
        }
499
0
    }
500
}
501
502
impl fmt::Debug for Message {
503
0
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
504
0
        let mut x = f.debug_struct("Message");
505
0
        x.field("Type", &self.msg_type());
506
        // The &&** derefs to a &&str, which implements &dyn Debug
507
0
        if let Some(ref path) = self.path() { x.field("Path", &&**path); }
508
0
        if let Some(ref iface) = self.interface() { x.field("Interface", &&**iface); }
509
0
        if let Some(ref member) = self.member() { x.field("Member", &&**member); }
510
0
        if let Some(ref sender) = self.sender() { x.field("Sender", &&**sender); }
511
0
        if let Some(ref dest) = self.destination() { x.field("Destination", &&**dest); }
512
0
        if let Some(ref serial) = self.get_serial() { x.field("Serial", serial); }
513
0
        if let Some(ref rs) = self.get_reply_serial() { x.field("ReplySerial", rs); }
514
0
        let mut args = vec!();
515
0
        let mut iter = self.iter_init();
516
0
        while let Some(a) = iter.get_refarg() {
517
0
            args.push(a);
518
0
            iter.next();
519
0
        }
520
0
        let args2: &[_] = &args;
521
0
        x.field("Args", &args2);
522
0
        x.finish()
523
0
    }
524
}
525
526
#[cfg(test)]
527
mod test {
528
    use crate::{Message};
529
    use crate::strings::BusName;
530
531
    #[test]
532
    fn set_valid_destination() {
533
        let mut m = Message::new_method_call("org.test.rust", "/", "org.test.rust", "Test").unwrap();
534
        let d = Some(BusName::new(":1.14").unwrap());
535
        m.set_destination(d);
536
537
        assert!(!m.get_no_reply());
538
        m.set_no_reply(true);
539
        assert!(m.get_no_reply());
540
    }
541
542
    #[test]
543
    fn marshal() {
544
        let mut m = Message::new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "Hello").unwrap();
545
        m.set_serial(1);
546
        let r = m.marshal(|d| {
547
            let m2 = Message::demarshal(d).unwrap();
548
            assert_eq!(&*m2.path().unwrap(), "/org/freedesktop/DBus");
549
            Err(45)
550
        });
551
        assert_eq!(45, r.unwrap_err());
552
    }
553
}