tokio_dbus_runtime/connection.rs
1use std::collections::VecDeque;
2use std::fmt;
3use std::future::Future;
4use std::pin::{Pin, pin};
5use std::task::{Context, Poll};
6use std::time::Duration;
7
8use tokio::time::{Instant, Sleep};
9
10use tokio_dbus::org_freedesktop_dbus::{self, NameFlag, NameReply};
11use tokio_dbus::{
12 Alignment, Body, BodyBuf, Buffers, MessageBuf, MessageKind, ObjectPath, RawArray, Serial,
13 Signature,
14};
15
16use crate::error::ErrorKind;
17use crate::{Decode, Encode, Error, Result};
18
19/// The body of a message being built.
20///
21/// The signature of the arguments is declared up front, since generated code
22/// knows it at build time, after which each argument is written in order.
23///
24/// # Examples
25///
26/// ```
27/// use tokio_dbus::Signature;
28/// use tokio_dbus_runtime::Arguments;
29///
30/// let mut arguments = Arguments::new(Signature::new("su")?)?;
31/// arguments.store("Hello World!");
32/// arguments.store(&42u32);
33/// # Ok::<_, tokio_dbus_runtime::Error>(())
34/// ```
35#[derive(Default)]
36pub struct Arguments {
37 buf: BodyBuf,
38}
39
40impl Arguments {
41 /// Construct an argument list matching the given signature.
42 pub fn new(signature: &Signature) -> Result<Self> {
43 let mut buf = BodyBuf::new();
44 buf.extend_signature(signature)?;
45 Ok(Self { buf })
46 }
47
48 /// Construct an argument list matching a signature which is known at
49 /// compile time.
50 ///
51 /// This is the infallible form of [`new()`], for the common case where the
52 /// signature comes out of [`Signature::new_const`] and has therefore
53 /// already been validated at compile time.
54 ///
55 /// [`new()`]: Self::new
56 ///
57 /// # Examples
58 ///
59 /// ```
60 /// use tokio_dbus::Signature;
61 /// use tokio_dbus_runtime::Arguments;
62 ///
63 /// const SIGNATURE: &Signature = Signature::new_const(b"su");
64 ///
65 /// let mut arguments = Arguments::new_const(SIGNATURE);
66 /// arguments.store("Hello World!");
67 /// arguments.store(&42u32);
68 /// ```
69 pub fn new_const(signature: &'static Signature) -> Self {
70 let mut buf = BodyBuf::new();
71
72 // NB: Extending an empty buffer with an already validated signature
73 // cannot fail, since the only failure is the combined signature growing
74 // too long.
75 buf.extend_signature(signature)
76 .expect("A validated signature cannot fail to extend an empty body");
77
78 Self { buf }
79 }
80
81 /// Construct an empty argument list.
82 pub fn empty() -> Self {
83 Self::default()
84 }
85
86 /// Write the next argument.
87 pub fn store<T>(&mut self, value: T) -> &mut Self
88 where
89 T: Encode,
90 {
91 value.encode(&mut self.buf.raw());
92 self
93 }
94
95 /// Write the next argument as a variant containing a value of the given
96 /// type.
97 ///
98 /// The signature is the one of the value inside the variant, not the `v` of
99 /// the variant itself.
100 ///
101 /// # Examples
102 ///
103 /// ```
104 /// use tokio_dbus::Signature;
105 /// use tokio_dbus_runtime::Arguments;
106 ///
107 /// let mut arguments = Arguments::new(Signature::VARIANT)?;
108 /// arguments.store_variant(Signature::UINT32, 42u32);
109 /// # Ok::<_, tokio_dbus_runtime::Error>(())
110 /// ```
111 pub fn store_variant<T>(&mut self, signature: &Signature, value: T) -> &mut Self
112 where
113 T: Encode,
114 {
115 let mut raw = self.buf.raw();
116 raw.store_signature(signature);
117 value.encode(&mut raw);
118 self
119 }
120
121 /// Write the next argument as an `a{sv}`, which is how a set of properties
122 /// of differing types is carried.
123 ///
124 /// # Examples
125 ///
126 /// ```
127 /// use tokio_dbus::Signature;
128 /// use tokio_dbus_runtime::Arguments;
129 ///
130 /// let mut arguments = Arguments::new(Signature::new("a{sv}")?)?;
131 ///
132 /// let mut dict = arguments.store_variant_dict();
133 /// dict.entry("Version", Signature::UINT32, 3u32);
134 /// dict.entry("Status", Signature::STRING, "normal");
135 /// dict.finish();
136 /// # Ok::<_, tokio_dbus_runtime::Error>(())
137 /// ```
138 pub fn store_variant_dict(&mut self) -> VariantDict<'_> {
139 VariantDict {
140 // NB: Dict entries are aligned just like structs.
141 array: self.buf.raw().into_array(Alignment::U64),
142 }
143 }
144
145 fn body(&self) -> Body<'_> {
146 self.buf.as_body()
147 }
148
149 #[cfg(test)]
150 pub(crate) fn body_for_test(&self) -> Body<'_> {
151 self.body()
152 }
153}
154
155/// A writer for an `a{sv}`, where every value is a variant of its own type.
156///
157/// See [`Arguments::store_variant_dict`].
158pub struct VariantDict<'a> {
159 array: RawArray<'a>,
160}
161
162impl VariantDict<'_> {
163 /// Write an entry, whose value is a variant containing a value of the given
164 /// type.
165 pub fn entry<T>(&mut self, name: &str, signature: &Signature, value: T) -> &mut Self
166 where
167 T: Encode,
168 {
169 let mut entry = self.array.as_raw();
170 entry.align(Alignment::U64);
171 name.encode(&mut entry);
172 entry.store_signature(signature);
173 value.encode(&mut entry);
174 self
175 }
176
177 /// Finish writing the dictionary.
178 ///
179 /// This also happens implicitly when the writer is dropped.
180 pub fn finish(self) {}
181}
182
183/// Read a variant which is expected to contain a value of type `T`.
184///
185/// # Examples
186///
187/// ```
188/// use tokio_dbus::{BodyBuf, Signature};
189/// use tokio_dbus_runtime::decode_variant;
190///
191/// let mut buf = BodyBuf::new();
192/// buf.store_variant(Signature::UINT32)?.store(42u32);
193///
194/// let mut body = buf.as_body();
195/// assert_eq!(decode_variant::<u32>(&mut body, Signature::UINT32)?, 42);
196/// # Ok::<_, tokio_dbus_runtime::Error>(())
197/// ```
198pub fn decode_variant<T>(body: &mut Body<'_>, expected: &Signature) -> Result<T>
199where
200 T: Decode,
201{
202 let signature = body.read::<Signature>()?;
203
204 if signature != expected {
205 return Err(Error::new(ErrorKind::UnexpectedSignature(Box::new((
206 expected.to_owned(),
207 signature.to_owned(),
208 )))));
209 }
210
211 T::decode(body)
212}
213
214impl fmt::Debug for Arguments {
215 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216 f.debug_struct("Arguments")
217 .field("signature", &self.buf.signature())
218 .finish()
219 }
220}
221
222/// A connection to a bus which speaks in owned Rust values.
223///
224/// This is the driver used by generated clients and servers. It wraps a
225/// [`tokio_dbus::Connection`] and takes care of matching replies to calls,
226/// buffering the messages which arrive while a call is outstanding so that they
227/// can be dispatched later.
228///
229/// Incoming messages are copied out of the receive buffer so that the connection
230/// stays usable while one is being handled. Use the low level API directly if
231/// that copy matters.
232pub struct Connection {
233 connection: tokio_dbus::Connection,
234 buffers: Buffers,
235 /// Messages which arrived while waiting for the reply to a call.
236 queue: VecDeque<MessageBuf>,
237 unique_name: String,
238 /// How long to wait for the reply to a call before giving up.
239 timeout: Option<Duration>,
240 /// The timer driving call timeouts, created on the first timed call and
241 /// reused for every one after that. See [`wait_for()`][Self::wait_for].
242 sleep: Option<Pin<Box<Sleep>>>,
243}
244
245impl Connection {
246 /// The default for how long a call waits for its reply, matching the 25
247 /// seconds every other D-Bus implementation defaults to.
248 pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(25);
249
250 /// Connect to the session bus and say `Hello`.
251 pub async fn session_bus() -> Result<Self> {
252 Self::start(tokio_dbus::Connection::session_bus()?).await
253 }
254
255 /// Connect to the system bus and say `Hello`.
256 pub async fn system_bus() -> Result<Self> {
257 Self::start(tokio_dbus::Connection::system_bus()?).await
258 }
259
260 async fn start(connection: tokio_dbus::Connection) -> Result<Self> {
261 let mut this = Self {
262 connection,
263 buffers: Buffers::new(),
264 queue: VecDeque::new(),
265 unique_name: String::new(),
266 timeout: Some(Self::DEFAULT_TIMEOUT),
267 sleep: None,
268 };
269
270 this.connection.connect(&mut this.buffers).await?;
271
272 let serial = this.buffers.hello()?;
273 let reply = this.wait_for(serial).await?;
274
275 let Ok(name) = reply.body().read::<str>() else {
276 return Err(Error::new(ErrorKind::MissingUniqueName));
277 };
278
279 this.unique_name = name.to_owned();
280 Ok(this)
281 }
282
283 /// The unique name the bus assigned to this connection, such as `:1.42`.
284 pub fn unique_name(&self) -> &str {
285 &self.unique_name
286 }
287
288 /// Set how long a call waits for its reply before failing, or `None` to
289 /// wait forever.
290 ///
291 /// The default is [`DEFAULT_TIMEOUT`], since the bus does not time method
292 /// calls out on its own, a peer which is alive but not reading its socket
293 /// would otherwise hang the caller forever. The timeout applies to
294 /// everything which waits for a reply, including [`call()`] and the name
295 /// and match management methods.
296 ///
297 /// A call which times out fails with an error for which
298 /// [`Error::is_timeout()`] is true and whose [`Error::name()`] is
299 /// `org.freedesktop.DBus.Error.NoReply`. The connection itself remains
300 /// usable, a reply which arrives after the deadline is discarded.
301 ///
302 /// The timeout is driven by the Tokio timer, which must be enabled on the
303 /// runtime. `#[tokio::main]` enables it by default.
304 ///
305 /// [`DEFAULT_TIMEOUT`]: Self::DEFAULT_TIMEOUT
306 /// [`call()`]: Self::call
307 pub fn set_default_timeout(&mut self, timeout: Option<Duration>) {
308 self.timeout = timeout;
309 }
310
311 /// How long a call waits for its reply before failing, if limited.
312 ///
313 /// See [`set_default_timeout()`][Self::set_default_timeout].
314 pub fn default_timeout(&self) -> Option<Duration> {
315 self.timeout
316 }
317
318 /// Call a method and wait for its reply.
319 ///
320 /// An error reply is turned into an [`Error`] carrying the name the remote
321 /// end used.
322 ///
323 /// The call fails with a timeout error when no reply arrives within the
324 /// configured deadline, see
325 /// [`set_default_timeout()`][Self::set_default_timeout].
326 ///
327 /// # Cancellation
328 ///
329 /// This method is cancel safe. If the future is dropped before it
330 /// completes, the call itself may still reach the peer, but the connection
331 /// remains usable and a reply which arrives later is discarded rather than
332 /// surfaced or confused with the reply to another call.
333 pub async fn call(
334 &mut self,
335 destination: &str,
336 path: &ObjectPath,
337 interface: &str,
338 member: &str,
339 arguments: &Arguments,
340 ) -> Result<Reply> {
341 let m = self
342 .buffers
343 .send
344 .method_call(path, member)
345 .with_destination(destination)
346 .with_interface(interface)
347 .with_body(arguments.body());
348
349 let serial = m.serial();
350 self.buffers.send.write_message(m)?;
351 let message = self.wait_for(serial).await?;
352 Ok(Reply { message })
353 }
354
355 /// Emit a signal.
356 ///
357 /// Signals are buffered and written out the next time the connection makes
358 /// progress. Call [`flush()`] to force them out.
359 ///
360 /// [`flush()`]: Self::flush
361 pub fn emit(
362 &mut self,
363 path: &ObjectPath,
364 interface: &str,
365 member: &str,
366 arguments: &Arguments,
367 ) -> Result<()> {
368 let m = self
369 .buffers
370 .send
371 .signal(path, member)
372 .with_interface(interface)
373 .with_body(arguments.body());
374
375 self.buffers.send.write_message(m)?;
376 Ok(())
377 }
378
379 /// Reply to a method call.
380 pub fn reply(&mut self, call: &Call, arguments: &Arguments) -> Result<()> {
381 let m = call
382 .message
383 .borrow()
384 .method_return(self.buffers.send.next_serial())
385 .with_body(arguments.body());
386
387 self.buffers.send.write_message(m)?;
388 Ok(())
389 }
390
391 /// Reply to a method call with an error.
392 pub fn reply_error(&mut self, call: &Call, error: &Error) -> Result<()> {
393 let name = error
394 .name()
395 .unwrap_or(org_freedesktop_dbus::FAILED_ERROR)
396 .to_owned();
397
398 let mut arguments = Arguments::new_const(Signature::STRING);
399 arguments.store(error.to_string().as_str());
400
401 let m = call
402 .message
403 .borrow()
404 .error(&name, self.buffers.send.next_serial())
405 .with_body(arguments.body());
406
407 self.buffers.send.write_message(m)?;
408 Ok(())
409 }
410
411 /// Request ownership of a well known name.
412 pub async fn request_name(&mut self, name: &str, flags: NameFlag) -> Result<NameReply> {
413 let serial = self.buffers.request_name(name, flags)?;
414 let reply = self.wait_for(serial).await?;
415 Ok(reply.body().load::<NameReply>()?)
416 }
417
418 /// Request ownership of a well known name, erroring unless it was acquired.
419 pub async fn acquire_name(&mut self, name: &str, flags: NameFlag) -> Result<()> {
420 match self.request_name(name, flags).await? {
421 NameReply::PRIMARY_OWNER | NameReply::ALREADY_OWNER => Ok(()),
422 _ => Err(Error::new(ErrorKind::NameTaken(name.into()))),
423 }
424 }
425
426 /// Release a well known name previously acquired.
427 pub async fn release_name(&mut self, name: &str) -> Result<()> {
428 let serial = self.buffers.release_name(name)?;
429 self.wait_for(serial).await?;
430 Ok(())
431 }
432
433 /// Add a match rule, so that the bus routes matching signals here.
434 pub async fn add_match(&mut self, rule: &str) -> Result<()> {
435 let serial = self.buffers.add_match(rule)?;
436 self.wait_for(serial).await?;
437 Ok(())
438 }
439
440 /// Remove a match rule.
441 pub async fn remove_match(&mut self, rule: &str) -> Result<()> {
442 let serial = self.buffers.remove_match(rule)?;
443 self.wait_for(serial).await?;
444 Ok(())
445 }
446
447 /// Ask the bus to route [`NameOwnerChanged`] signals for `name` here.
448 ///
449 /// Watching a name is how a client survives its peer restarting: the
450 /// signal announces both the name going away and it being claimed again.
451 /// Decode the incoming signal with [`NameOwnerChanged::decode`], and pair
452 /// this with [`name_owner()`] to learn the initial state, since the signal
453 /// only reports changes.
454 ///
455 /// [`NameOwnerChanged`]: crate::NameOwnerChanged
456 /// [`NameOwnerChanged::decode`]: crate::NameOwnerChanged::decode
457 /// [`name_owner()`]: Self::name_owner
458 pub async fn watch_name(&mut self, name: &str) -> Result<()> {
459 self.add_match(&crate::NameOwnerChanged::rule(name)).await
460 }
461
462 /// Remove the interest registered by [`watch_name()`][Self::watch_name].
463 pub async fn unwatch_name(&mut self, name: &str) -> Result<()> {
464 self.remove_match(&crate::NameOwnerChanged::rule(name))
465 .await
466 }
467
468 /// The unique name currently owning `name`, or `None` when the name has no
469 /// owner.
470 pub async fn name_owner(&mut self, name: &str) -> Result<Option<String>> {
471 let mut arguments = Arguments::new_const(Signature::STRING);
472 arguments.store(name);
473
474 let result = self
475 .call(
476 org_freedesktop_dbus::DESTINATION,
477 org_freedesktop_dbus::PATH,
478 org_freedesktop_dbus::INTERFACE,
479 "GetNameOwner",
480 &arguments,
481 )
482 .await;
483
484 match result {
485 Ok(reply) => Ok(Some(reply.read::<String>()?)),
486 Err(error) if error.name() == Some(org_freedesktop_dbus::NAME_HAS_NO_OWNER_ERROR) => {
487 Ok(None)
488 }
489 Err(error) => Err(error),
490 }
491 }
492
493 /// Reply to a method call which no dispatcher recognised.
494 ///
495 /// The generated `dispatch` functions return `false` for a call which is
496 /// not theirs, so that several interfaces can be served from one
497 /// connection. Once every dispatcher has declined, this produces the
498 /// standard `org.freedesktop.DBus.Error.UnknownMethod` reply leaving the
499 /// call unanswered would leave the caller waiting for its timeout instead.
500 pub fn reply_unknown_method(&mut self, call: &Call) -> Result<()> {
501 self.reply_error(
502 call,
503 &Error::remote(
504 org_freedesktop_dbus::UNKNOWN_METHOD_ERROR,
505 format_args!(
506 "No such method: {}.{}",
507 call.interface().unwrap_or_default(),
508 call.member()
509 ),
510 ),
511 )
512 }
513
514 /// Write out everything which has been buffered for sending.
515 ///
516 /// This is only needed before dropping the connection, since [`next()`] and
517 /// [`call()`] both drive writes as a side effect.
518 ///
519 /// [`next()`]: Self::next
520 /// [`call()`]: Self::call
521 pub async fn flush(&mut self) -> Result<()> {
522 self.connection.flush(&mut self.buffers).await?;
523
524 if self.buffers.recv.has_message() {
525 let message = self.buffers.recv.last_message()?.to_owned();
526 self.queue.push_back(message);
527 self.buffers.recv.clear();
528 }
529
530 Ok(())
531 }
532
533 /// Wait for the next method call or signal directed at this connection.
534 pub async fn next(&mut self) -> Result<Incoming> {
535 loop {
536 if let Some(message) = self.queue.pop_front() {
537 if let Some(incoming) = Incoming::new(message) {
538 return Ok(incoming);
539 }
540
541 continue;
542 }
543
544 self.connection.wait(&mut self.buffers).await?;
545 let message = self.buffers.recv.last_message()?.to_owned();
546
547 if let Some(incoming) = Incoming::new(message) {
548 return Ok(incoming);
549 }
550 }
551 }
552
553 /// Wait for the reply with the given serial, applying the configured
554 /// timeout.
555 async fn wait_for(&mut self, serial: Serial) -> Result<MessageBuf> {
556 let Self {
557 connection,
558 buffers,
559 queue,
560 timeout,
561 sleep,
562 ..
563 } = self;
564
565 let future = pin!(drive_until_reply(connection, buffers, queue, serial));
566
567 let Some(timeout) = *timeout else {
568 return future.await;
569 };
570
571 let deadline = Instant::now() + timeout;
572
573 // The timer is created on the first timed call and reset for each one
574 // after that, and is deliberately never cancelled: resetting a timer
575 // which is still registered with the runtime to a later deadline is a
576 // lock-free store, where registering a fresh one locks the timer
577 // wheel. A deadline which fires with no call outstanding wakes the
578 // last caller once, spuriously and harmlessly.
579 let sleep = match sleep {
580 Some(sleep) => {
581 sleep.as_mut().reset(deadline);
582 sleep
583 }
584 sleep => sleep.insert(Box::pin(tokio::time::sleep_until(deadline))),
585 };
586
587 Timed {
588 future,
589 sleep: sleep.as_mut(),
590 timeout,
591 }
592 .await
593 }
594}
595
596/// Drive the connection until the reply with the given serial arrives,
597/// queueing everything else which shows up in the meantime.
598///
599/// This is a function over the fields it needs rather than a method, so that
600/// the timer of the connection stays borrowable next to it.
601async fn drive_until_reply(
602 connection: &mut tokio_dbus::Connection,
603 buffers: &mut Buffers,
604 queue: &mut VecDeque<MessageBuf>,
605 serial: Serial,
606) -> Result<MessageBuf> {
607 loop {
608 connection.wait(buffers).await?;
609 let message = buffers.recv.last_message()?;
610
611 match message.kind() {
612 MessageKind::MethodReturn { reply_serial } if reply_serial == serial => {
613 return Ok(message.to_owned());
614 }
615 MessageKind::Error {
616 error_name,
617 reply_serial,
618 } if reply_serial == serial => {
619 let text = message.body().read::<str>().unwrap_or_default();
620 return Err(Error::remote(error_name, text));
621 }
622 _ => {
623 let message = message.to_owned();
624 queue.push_back(message);
625 }
626 }
627 }
628}
629
630/// A future bounded by the reply deadline of the connection.
631///
632/// This is `tokio::time::timeout` with the timer borrowed rather than owned, so
633/// that however the wait ends, completion, cancellation or an unwinding panic,
634/// the timer stays in the connection for the next call to reuse.
635struct Timed<'a, F> {
636 future: Pin<&'a mut F>,
637 sleep: Pin<&'a mut Sleep>,
638 timeout: Duration,
639}
640
641impl<T, F> Future for Timed<'_, F>
642where
643 F: Future<Output = Result<T>>,
644{
645 type Output = Result<T>;
646
647 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
648 // NB: The future is polled first so that a reply which is ready wins
649 // over a deadline which elapsed while waiting.
650 if let Poll::Ready(result) = self.future.as_mut().poll(cx) {
651 return Poll::Ready(result);
652 }
653
654 if self.sleep.as_mut().poll(cx).is_ready() {
655 return Poll::Ready(Err(Error::new(ErrorKind::Timeout(self.timeout))));
656 }
657
658 Poll::Pending
659 }
660}
661
662/// The reply to a method call.
663pub struct Reply {
664 message: MessageBuf,
665}
666
667impl Reply {
668 /// The body of the reply, from which the return values are read.
669 pub fn body(&self) -> Body<'_> {
670 self.message.body()
671 }
672
673 /// Read a single return value.
674 pub fn read<T>(&self) -> Result<T>
675 where
676 T: Decode,
677 {
678 T::decode(&mut self.body())
679 }
680}
681
682impl fmt::Debug for Reply {
683 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
684 self.message.fmt(f)
685 }
686}
687
688/// A message which arrived on the connection and is not a reply.
689#[derive(Debug)]
690#[non_exhaustive]
691pub enum Incoming {
692 /// A method call which is expected to be replied to.
693 Call(Call),
694 /// A signal, which is never replied to.
695 Signal(SignalMessage),
696}
697
698impl Incoming {
699 fn new(message: MessageBuf) -> Option<Self> {
700 match message.kind() {
701 MessageKind::MethodCall { .. } => Some(Incoming::Call(Call { message })),
702 MessageKind::Signal { .. } => Some(Incoming::Signal(SignalMessage { message })),
703 // NB: A reply which nothing is waiting for anymore.
704 _ => None,
705 }
706 }
707}
708
709/// An incoming method call.
710pub struct Call {
711 message: MessageBuf,
712}
713
714impl Call {
715 /// The object the call is addressed to.
716 pub fn path(&self) -> &ObjectPath {
717 match self.message.kind() {
718 MessageKind::MethodCall { path, .. } => path,
719 _ => unreachable!("Only constructed from a method call"),
720 }
721 }
722
723 /// The method being called.
724 pub fn member(&self) -> &str {
725 match self.message.kind() {
726 MessageKind::MethodCall { member, .. } => member,
727 _ => unreachable!("Only constructed from a method call"),
728 }
729 }
730
731 /// The interface the method belongs to, if the caller named one.
732 pub fn interface(&self) -> Option<&str> {
733 self.message.interface()
734 }
735
736 /// The unique name of the caller.
737 pub fn sender(&self) -> Option<&str> {
738 self.message.sender()
739 }
740
741 /// The body of the call, from which the arguments are read.
742 pub fn body(&self) -> Body<'_> {
743 self.message.body()
744 }
745}
746
747impl fmt::Debug for Call {
748 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
749 f.debug_struct("Call")
750 .field("path", &self.path())
751 .field("interface", &self.interface())
752 .field("member", &self.member())
753 .finish()
754 }
755}
756
757/// An incoming signal.
758pub struct SignalMessage {
759 message: MessageBuf,
760}
761
762impl SignalMessage {
763 /// The object which emitted the signal.
764 pub fn path(&self) -> &ObjectPath {
765 match self.message.kind() {
766 MessageKind::Signal { path, .. } => path,
767 _ => unreachable!("Only constructed from a signal"),
768 }
769 }
770
771 /// The name of the signal.
772 pub fn member(&self) -> &str {
773 match self.message.kind() {
774 MessageKind::Signal { member, .. } => member,
775 _ => unreachable!("Only constructed from a signal"),
776 }
777 }
778
779 /// The interface the signal belongs to, if the sender named one.
780 pub fn interface(&self) -> Option<&str> {
781 self.message.interface()
782 }
783
784 /// The unique name of the sender.
785 pub fn sender(&self) -> Option<&str> {
786 self.message.sender()
787 }
788
789 /// The body of the signal, from which its arguments are read.
790 pub fn body(&self) -> Body<'_> {
791 self.message.body()
792 }
793}
794
795impl fmt::Debug for SignalMessage {
796 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
797 f.debug_struct("SignalMessage")
798 .field("path", &self.path())
799 .field("interface", &self.interface())
800 .field("member", &self.member())
801 .finish()
802 }
803}