zbus/object_server/
dispatch_notifier.rs

1//! The object server API.
2
3use event_listener::{Event, EventListener};
4use serde::{Deserialize, Serialize};
5
6use zvariant::{Signature, Type};
7
8/// A response wrapper that notifies after the response has been sent.
9///
10/// Sometimes in [`interface`] method implementations we need to do some other work after the
11/// response has been sent off. This wrapper type allows us to do that. Instead of returning your
12/// intended response type directly, wrap it in this type and return it from your method. The
13/// returned `EventListener` from the `new` method will be notified when the response has been sent.
14///
15/// A typical use case is sending off signals after the response has been sent. The easiest way to
16/// do that is to spawn a task from the method that sends the signal but only after being notified
17/// of the response dispatch.
18///
19/// # Caveats
20///
21/// The notification indicates that the response has been sent off, not that destination peer has
22/// received it. That can only be guaranteed for a peer-to-peer connection.
23///
24/// [`interface`]: crate::interface
25#[derive(Debug)]
26pub struct ResponseDispatchNotifier<R> {
27    response: R,
28    event: Option<Event>,
29}
30
31impl<R> ResponseDispatchNotifier<R> {
32    /// Create a new `NotifyResponse`.
33    pub fn new(response: R) -> (Self, EventListener) {
34        let event = Event::new();
35        let listener = event.listen();
36        (
37            Self {
38                response,
39                event: Some(event),
40            },
41            listener,
42        )
43    }
44
45    /// Get the response.
46    pub fn response(&self) -> &R {
47        &self.response
48    }
49}
50
51impl<R> Serialize for ResponseDispatchNotifier<R>
52where
53    R: Serialize,
54{
55    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
56    where
57        S: serde::Serializer,
58    {
59        self.response.serialize(serializer)
60    }
61}
62
63impl<'de, R> Deserialize<'de> for ResponseDispatchNotifier<R>
64where
65    R: Deserialize<'de>,
66{
67    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
68    where
69        D: serde::Deserializer<'de>,
70    {
71        Ok(Self {
72            response: R::deserialize(deserializer)?,
73            event: None,
74        })
75    }
76}
77
78impl<R> Type for ResponseDispatchNotifier<R>
79where
80    R: Type,
81{
82    const SIGNATURE: &'static Signature = R::SIGNATURE;
83}
84
85impl<T> Drop for ResponseDispatchNotifier<T> {
86    fn drop(&mut self) {
87        if let Some(event) = self.event.take() {
88            event.notify(usize::MAX);
89        }
90    }
91}