1
1
// Take a look at the license at the top of the repository in the LICENSE file.
2
2
3
- use std:: { boxed:: Box as Box_ , num:: NonZeroU32 } ;
4
-
5
- use glib:: { prelude:: * , translate:: * } ;
3
+ use std:: { boxed:: Box as Box_ , future:: Future , marker:: PhantomData , num:: NonZeroU32 } ;
6
4
7
5
use crate :: {
8
6
ffi, ActionGroup , DBusConnection , DBusInterfaceInfo , DBusMessage , DBusMethodInvocation ,
9
7
DBusSignalFlags , MenuModel ,
10
8
} ;
9
+ use glib:: { prelude:: * , translate:: * } ;
10
+
11
+ pub trait DBusMethodCall : Sized {
12
+ fn parse_call (
13
+ obj_path : & str ,
14
+ interface : & str ,
15
+ method : & str ,
16
+ params : glib:: Variant ,
17
+ ) -> Result < Self , glib:: Error > ;
18
+ }
19
+
20
+ // rustdoc-stripper-ignore-next
21
+ /// Handle method invocations.
22
+ pub struct MethodCallBuilder < ' a , T > {
23
+ registration : RegistrationBuilder < ' a > ,
24
+ capture_type : PhantomData < T > ,
25
+ }
26
+
27
+ impl < ' a , T : DBusMethodCall > MethodCallBuilder < ' a , T > {
28
+ // rustdoc-stripper-ignore-next
29
+ /// Handle invocation of a parsed method call.
30
+ ///
31
+ /// For each DBus method call parse the call, and then invoke the given closure
32
+ /// with
33
+ ///
34
+ /// 1. the DBus connection object,
35
+ /// 2. the name of the sender of the method call,
36
+ /// 3. the parsed call, and
37
+ /// 4. the method invocation object.
38
+ ///
39
+ /// The closure **must** return a value through the invocation object in all
40
+ /// code paths, using any of its `return_` functions, such as
41
+ /// [`DBusMethodInvocation::return_result`] or
42
+ /// [`DBusMethodInvocation::return_future_local`], to finish the call.
43
+ ///
44
+ /// If direct access to the invocation object is not needed,
45
+ /// [`invoke_and_return`] and [`invoke_and_return_future_local`] provide a
46
+ /// safer interface where the callback returns a result directly.
47
+ pub fn invoke < F > ( self , f : F ) -> RegistrationBuilder < ' a >
48
+ where
49
+ F : Fn ( DBusConnection , & str , T , DBusMethodInvocation ) + ' static ,
50
+ {
51
+ self . registration . method_call (
52
+ move |connection, sender, obj_path, interface, method, params, invocation| {
53
+ match T :: parse_call ( obj_path, interface, method, params) {
54
+ Ok ( call) => f ( connection, sender, call, invocation) ,
55
+ Err ( error) => invocation. return_gerror ( error) ,
56
+ }
57
+ } ,
58
+ )
59
+ }
60
+
61
+ // rustdoc-stripper-ignore-next
62
+ /// Handle invocation of a parsed method call.
63
+ ///
64
+ /// For each DBus method call parse the call, and then invoke the given closure
65
+ /// with
66
+ ///
67
+ /// 1. the DBus connection object,
68
+ /// 2. the name of the sender of the method call, and
69
+ /// 3. the parsed call.
70
+ ///
71
+ /// The return value of the closure is then returned on the method call.
72
+ /// If the returned variant value is not a tuple, it is automatically wrapped
73
+ /// in a single element tuple, as DBus methods must always return tuples.
74
+ /// See [`DBusMethodInvocation::return_result`] for details.
75
+ pub fn invoke_and_return < F > ( self , f : F ) -> RegistrationBuilder < ' a >
76
+ where
77
+ F : Fn ( DBusConnection , & str , T ) -> Result < Option < glib:: Variant > , glib:: Error > + ' static ,
78
+ {
79
+ self . invoke ( move |connection, sender, call, invocation| {
80
+ invocation. return_result ( f ( connection, sender, call) )
81
+ } )
82
+ }
83
+
84
+ // rustdoc-stripper-ignore-next
85
+ /// Handle an async invocation of a parsed method call.
86
+ ///
87
+ /// For each DBus method call parse the call, and then invoke the given closure
88
+ /// with
89
+ ///
90
+ /// 1. the DBus connection object,
91
+ /// 2. the name of the sender of the method call, and
92
+ /// 3. the parsed call.
93
+ ///
94
+ /// The output of the future is then returned on the method call.
95
+ /// If the returned variant value is not a tuple, it is automatically wrapped
96
+ /// in a single element tuple, as DBus methods must always return tuples.
97
+ /// See [`DBusMethodInvocation::return_future_local`] for details.
98
+ pub fn invoke_and_return_future_local < F , Fut > ( self , f : F ) -> RegistrationBuilder < ' a >
99
+ where
100
+ F : Fn ( DBusConnection , & str , T ) -> Fut + ' static ,
101
+ Fut : Future < Output = Result < Option < glib:: Variant > , glib:: Error > > + ' static ,
102
+ {
103
+ self . invoke ( move |connection, sender, call, invocation| {
104
+ invocation. return_future_local ( f ( connection, sender, call) ) ;
105
+ } )
106
+ }
107
+ }
11
108
12
109
#[ derive( Debug , Eq , PartialEq ) ]
13
110
pub struct RegistrationId ( NonZeroU32 ) ;
@@ -22,6 +119,8 @@ pub struct FilterId(NonZeroU32);
22
119
#[ derive( Debug , Eq , PartialEq ) ]
23
120
pub struct SignalSubscriptionId ( NonZeroU32 ) ;
24
121
122
+ // rustdoc-stripper-ignore-next
123
+ /// Build a registered DBus object, by handling different parts of DBus.
25
124
#[ must_use = "The builder must be built to be used" ]
26
125
pub struct RegistrationBuilder < ' a > {
27
126
connection : & ' a DBusConnection ,
@@ -38,7 +137,7 @@ pub struct RegistrationBuilder<'a> {
38
137
Option < Box_ < dyn Fn ( DBusConnection , & str , & str , & str , & str , glib:: Variant ) -> bool > > ,
39
138
}
40
139
41
- impl RegistrationBuilder < ' _ > {
140
+ impl < ' a > RegistrationBuilder < ' a > {
42
141
pub fn method_call <
43
142
F : Fn ( DBusConnection , & str , & str , & str , & str , glib:: Variant , DBusMethodInvocation ) + ' static ,
44
143
> (
@@ -49,6 +148,19 @@ impl RegistrationBuilder<'_> {
49
148
self
50
149
}
51
150
151
+ // rustdoc-stripper-ignore-next
152
+ /// Handle method calls on this object.
153
+ ///
154
+ /// Return a builder for method calls which parses method names and
155
+ /// parameters with the given [`DBusMethodCall`] and then allows to dispatch
156
+ /// the parsed call either synchronously or asynchronously.
157
+ pub fn typed_method_call < T : DBusMethodCall > ( self ) -> MethodCallBuilder < ' a , T > {
158
+ MethodCallBuilder {
159
+ registration : self ,
160
+ capture_type : Default :: default ( ) ,
161
+ }
162
+ }
163
+
52
164
#[ doc( alias = "get_property" ) ]
53
165
pub fn property < F : Fn ( DBusConnection , & str , & str , & str , & str ) -> glib:: Variant + ' static > (
54
166
mut self ,
0 commit comments